it-swarm.com.de

Richtige Methode zum Initialisieren von C ++ - Strukturen

Unser Code beinhaltet eine POD-Struktur (Plain Old Datastructure) (es ist eine grundlegende c ++ - Struktur, die andere Strukturen und POD-Variablen enthält, die zu Beginn initialisiert werden müssen.)

Basierend auf dem, was ich gelesen habe, scheint es, dass:

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

sollte alle Werte auf Null initialisieren, ebenso wie:

myStruct = new MyStruct();

Wenn die Struktur jedoch auf die zweite Art initialisiert wird, beschwert sich Valgrind später, dass "ein bedingter Sprung oder eine bedingte Bewegung von nicht initialisierten Werten abhängt", wenn diese Variablen verwendet werden. Ist mein Verständnis hier fehlerhaft oder wirft Valgrind falsch positive Ergebnisse?

69
Shadow503

In C++ sind Klassen/Strukturen identisch (in Bezug auf die Initialisierung).

Eine Nicht-POD-Struktur kann auch einen Konstruktor haben, um Mitglieder zu initialisieren.
Wenn Ihre Struktur ein POD ist, können Sie einen Initialisierer verwenden.

struct C
{
    int x; 
    int y;
};

C  c = {0}; // Zero initialize POD

Alternativ können Sie den Standardkonstruktor verwenden.

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).

Ich glaube, Valgrind beschwert sich, weil C++ so funktioniert hat. (Ich bin nicht genau sicher, wann C++ mit der Null-Initialisierungs-Standardkonstruktion aktualisiert wurde). Am besten fügen Sie einen Konstruktor hinzu, der das Objekt initialisiert (Strukturen sind zugelassene Konstruktoren).

Als Randnotiz:
Viele Anfänger versuchen, init zu schätzen:

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();

Eine schnelle Suche nach "Most Vexing Parse" liefert eine bessere Erklärung als ich.

102
Martin York

Nach dem, was Sie uns gesagt haben, scheint es sich bei valgrind um ein falsches Positiv zu handeln. Die new Syntax mit () sollte das Objekt mit einem Wert initialisieren, vorausgesetzt, es ist POD.

Ist es möglich, dass ein Teil Ihrer Struktur kein POD ist und dies die erwartete Initialisierung verhindert? Können Sie Ihren Code in ein postbares Beispiel vereinfachen, das immer noch den valgrind-Fehler kennzeichnet?

Alternativ kann es sein, dass Ihr Compiler POD-Strukturen nicht wirklich wertinitialisiert.

In jedem Fall ist es wahrscheinlich die einfachste Lösung, Konstruktoren zu schreiben, die für die Struktur/Unterteile benötigt werden.

2
Mark B

Ich schreibe einen 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 ++ kompilieren und ausführen:

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

Da es sich um eine POD-Struktur handelt, können Sie sie jederzeit auf 0 setzen. Dies ist möglicherweise der einfachste Weg, um die Felder zu initialisieren (sofern dies angemessen ist).

0
Scott C Wilson

Sie müssen alle Elemente in Ihrer Struktur initialisieren, z.

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;

  public:
    MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values

};
0
ralphtheninja