Forma adecuada de inicializar estructuras C++


Nuestro código implica una estructura POD (Plain Old Datastructure) (es una estructura básica de c++ que tiene otras estructuras y variables POD que deben inicializarse al principio.)

Basado en lo que he leído , parece que:

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

Debe inicializar todos los valores a cero, al igual que:

myStruct = new MyStruct();

Sin embargo, cuando la estructura se inicializa de la segunda manera, Valgrind se queja más tarde de que " el salto o movimiento condicional depende del(de los) valor (s) no inicializado (s)" se utilizan variables. ¿Mi entendimiento es erróneo aquí, o Valgrind está arrojando falsos positivos?

Author: Community, 2011-05-06

5 answers

En C++ las clases/estructuras son idénticas (en términos de inicialización).

Una estructura no POD también puede tener un constructor para que pueda inicializar miembros.
Si tu estructura es un POD, puedes usar un inicializador.

struct C
{
    int x; 
    int y;
};

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

Alternativamente puede usar el constructor predeterminado.

C  c = C();      // Zero initialize using default constructor
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).

Creo que valgrind se queja porque así es como solía funcionar C++. (No estoy exactamente seguro de cuándo se actualizó C++ con la construcción predeterminada de inicialización cero). Tu mejor apuesta es para agregar un constructor que inicializa el objeto (las estructuras son constructores permitidos).

Como nota al margen:
Muchos principiantes tratan de valorar init:

C c(); // Unfortunately this is not a variable declaration.

// The correct way to do this is:
C c = C();

Una búsqueda rápida del "Análisis más Irritante" proporcionará una mejor explicación que yo.

 84
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-20 16:09:48

Por lo que nos has dicho parece ser un falso positivo en valgrind. La sintaxis new con () debería inicializar el objeto, asumiendo que es POD.

¿Es posible que alguna subparte de su estructura no sea en realidad POD y eso impida la inicialización esperada? ¿Puede simplificar su código en un ejemplo postable que aún marque el error valgrind?

Alternativamente, tal vez su compilador no valore realmente-inicializar POD estructura.

En cualquier caso, probablemente la solución más simple es escribir constructores según sea necesario para la estructura/subpartes.

 2
Author: Mark B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-06 17:06:55

Necesita inicializar cualquier miembro que tenga en su estructura, por ejemplo:

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;

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

};
 1
Author: ralphtheninja,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-06 16:45:49

Escribo un código de prueba:

#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++ compilar y ejecutar:

./a.out 
132
az:0x2b0000002a
bz:0
a:854191480 yend
b:0 yend
aa:854190968 yend
ba:0 yend
 1
Author: Yadong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-21 01:25:36

Dado que es una estructura POD, siempre puede configurarla en 0 - esta podría ser la forma más fácil de inicializar los campos (suponiendo que sea apropiado).

 0
Author: Scott C Wilson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-06 17:19:17