De juiste manier om C++-structs te initialiseren

Onze code omvat een POD (Plain Old Datastructure)-struct (het is een basis-c++-struct die andere structs en POD-variabelen bevat die in het begin geïnitialiseerd moeten worden.)

Op basis van wat ik gelezenheb, lijkt het erop dat:

myStruct = (MyStruct*)calloc(1, sizeof(MyStruct));

moet alle waarden op nul initialiseren, net als:

myStruct = new MyStruct();

Als de struct echter op de tweede manier wordt geïnitialiseerd, klaagt Valgrind later dat “voorwaardelijke sprong of beweging afhankelijk is van niet-geïnitialiseerde waarde(n)” wanneer die variabelen worden gebruikt. Is mijn begrip hier gebrekkig, of gooit Valgrind valse positieven?


Antwoord 1, autoriteit 100%

In C++ zijn klassen/structs identiek (in termen van initialisatie).

Een niet-POD-struct kan net zo goed een constructor hebben zodat deze leden kan initialiseren.
Als je structuur een POD is, kun je een initializer gebruiken.

struct C
{
    int x; 
    int y;
};
C  c = {0}; // Zero initialize POD

Als alternatief kunt u de standaardconstructor gebruiken.

C  c = C();      // Zero initialize using default constructor
C  c{};          // Latest versions accept this syntax.
C* c = new C();  // Zero initialize a dynamically allocated object.
// Note the difference between the above and the initialize version of the constructor.
// Note: All above comments apply to POD structures.
C  c;            // members are random
C* c = new C;    // members are random (more officially undefined).

Ik geloof dat Valgrind klagen, want dat is hoe C++ gebruikt om te werken. (Ik weet niet precies wanneer C++ is geüpgraded met de standaardconstructie van de zero-initialisatie). Uw beste gok is om een ​​constructor toe te voegen die het object initialiseert (structuren zijn toegestane constructeurs).

als een kant opmerking:
Veel beginners proberen init init:

C c(); // Unfortunately this is not a variable declaration.
C c{}; // This syntax was added to overcome this confusion.
// The correct way to do this is:
C c = C();

Een snelle zoektocht naar de “MEEST VEXING PARSE” zal een betere verklaring bieden dan ik.


Antwoord 2, Autoriteit 2%

Van wat je ons hebt verteld dat het een vals positief lijkt te zijn in Valgrind. De newSyntaxis met ()moet waarderen – initialiseren het object, ervan uitgaande dat het pod is.

Is het mogelijk dat sommige subvaart van uw struct niet echt pod en dat verhindert de verwachte initialisatie? Kun je je code vereenvoudigen in een objecteerbaar voorbeeld dat nog steeds de valgrind-fout markeert?

Weid afwisselend misschien is uw compiler niet initialiseert – initialiseert POD-structuren.

In ieder geval is waarschijnlijk de eenvoudigste oplossing om constructor (s) te schrijven als nodig is voor de struct / subparts.


Antwoord 3

Ik schrijf een testcode:

#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
struct sc {
    int x;
    string y;
    int* z;
};
int main(int argc, char** argv)
{
   int* r = new int[128];
   for(int i = 0; i < 128; i++ ) {
        r[i] = i+32;
   }
   cout << r[100] << endl;
   delete r;
   sc* a = new sc;
   sc* aa = new sc[2];
   sc* b = new sc();
   sc* ba = new sc[2]();
   cout << "az:" << a->z << endl;
   cout << "bz:" << b->z << endl;
   cout << "a:" << a->x << " y" << a->y << "end" << endl;
   cout << "b:" << b->x << " y" << b->y <<  "end" <<endl;
   cout << "aa:" << aa->x << " y" << aa->y <<  "end" <<endl;
   cout << "ba:" << ba->x << " y" << ba->y <<  "end" <<endl;
}

g++ compileren en uitvoeren:

./a.out 
132
az:0x2b0000002a
bz:0
a:854191480 yend
b:0 yend
aa:854190968 yend
ba:0 yend

Antwoord 4

Je moet alle leden die je in je structuur hebt, initialiseren, bijvoorbeeld:

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;
  public:
    MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values
};

Antwoord 5

Aangezien het een POD-struct is, kun je deze altijd op 0 zetten – dit is misschien de gemakkelijkste manier om de velden te initialiseren (ervan uitgaande dat dit gepast is).


Antwoord 6

Dat lijkt mij de gemakkelijkste manier. Structuurelementen kunnen worden geïnitialiseerd met accolades ‘{}’. Hieronder volgt bijvoorbeeld een geldige initialisatie.

struct Point 
{ 
   int x, y; 
};  
int main() 
{ 
   // A valid initialization. member x gets value 0 and y 
   // gets value 1.  The order of declaration is followed. 
   struct Point p1 = {0, 1};  
}

Er is goede informatie over structs in c++ – https://www.geeksforgeeks.org /structures-in-cpp/

Other episodes