107 votes

La bonne façon d'initialiser les structures C++

Notre code implique une structure POD (Plain Old Datastructure) (il s'agit d'une structure C++ de base qui contient d'autres structures et des variables POD qui doivent être initialisées au début).

D'après ce que j'ai lire Il semble que :

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

devrait initialiser toutes les valeurs à zéro, comme le fait :

myStruct = new MyStruct();

Cependant, lorsque la structure est initialisée de la seconde manière, Valgrind se plaint plus tard que "conditional jump or move depends on uninitialised value(s)" (le saut ou le déplacement conditionnel dépend d'une ou de plusieurs valeurs non initialisées) lorsque ces variables sont utilisées. Est-ce que ma compréhension est erronée ou est-ce que Valgrind envoie des faux positifs ?

3voto

Yadong Points 11

J'écris un code de test :

#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++ compile et exécute :

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

2voto

Mark B Points 60200

D'après ce que vous nous avez dit, il semble qu'il s'agisse d'un faux positif dans valgrind. Les new syntaxe avec () devrait initialiser la valeur de l'objet, en supposant qu'il s'agisse d'un POD.

Est-il possible qu'une sous-partie de votre structure ne soit pas réellement POD et que cela empêche l'initialisation attendue ? Êtes-vous en mesure de simplifier votre code en un exemple publiable qui signale toujours l'erreur valgrind ?

Il se peut aussi que votre compilateur n'initialise pas les valeurs des structures POD.

Quoi qu'il en soit, la solution la plus simple consiste probablement à écrire le(s) constructeur(s) nécessaire(s) pour la structure/les sous-parties.

0voto

Scott Wilson Points 5160

Comme il s'agit d'une structure POD, vous pouvez toujours la mettre à 0 - c'est peut-être le moyen le plus simple d'initialiser les champs (en supposant que ce soit approprié).

0voto

ralphtheninja Points 24346

Vous devez initialiser tous les membres que vous avez dans votre structure, par exemple :

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;

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

};

0voto

Cela me semble être la solution la plus simple. Les membres de la structure peuvent être initialisés à l'aide d'accolades "{}". Par exemple, l'initialisation suivante est valide.

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};  
}

Il y a de bonnes informations sur les structs en c++ - https://www.geeksforgeeks.org/structures-in-cpp/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X