Правильный способ инициализации структур C ++ - PullRequest
67 голосов
/ 06 мая 2011

Наш код включает в себя структуру POD (Plain Old Datastructure) (это базовая структура c ++, в которой есть другие структуры и переменные POD, которые нужно инициализировать в начале.)

На основе той, что я've read , кажется, что:

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

должен инициализировать все значения в ноль, как это делается:

myStruct = new MyStruct();

Однако, когда структура инициализируетсяво-вторых, Valgrind позже жалуется на «условный переход или перемещение зависит от неинициализированных значений» при использовании этих переменных.Мое понимание здесь ошибочно, или Вальгринд выдает ложные срабатывания?

Ответы [ 5 ]

97 голосов
/ 06 мая 2011

В C ++ классы / структуры идентичны (с точки зрения инициализации).

Структура, отличная от POD, также может иметь конструктор, чтобы она могла инициализировать элементы.
Если ваша структура является POD, вы можете использовать инициализатор.

struct C
{
    int x; 
    int y;
};

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

В качестве альтернативы вы можете использовать конструктор по умолчанию.

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

Я полагаю, что valgrind жалуется, потому что так работал C ++. (Я не совсем уверен, когда C ++ был обновлен с конструкцией по умолчанию с нулевой инициализацией). Лучше всего добавить конструктор, который инициализирует объект (конструкции допускаются конструкторами).

В качестве примечания:
Многие новички пытаются оценить 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();

Быстрый поиск "Most Vexing Parse" даст лучшее объяснение, чем я.

2 голосов
/ 06 мая 2011

Судя по тому, что вы сказали нам, в valgrind это ложный позитив.Синтаксис new с () должен инициализировать значение объекта, предполагая, что это POD.

Возможно ли, что какая-то часть вашей структуры на самом деле не POD, и это предотвращает ожидаемую инициализацию?Можете ли вы упростить свой код до готового примера, который все еще отмечает ошибку valgrind?

С другой стороны, возможно, ваш компилятор на самом деле не инициализирует значения структур POD.

В любом случае, возможно, самый простойРешение состоит в том, чтобы написать конструктор (ы) по мере необходимости для struct / subparts.

1 голос
/ 21 января 2017

Я пишу тестовый код:

#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 ++ скомпилируйте и запустите:

./a.out 
132
az:0x2b0000002a
bz:0
a:854191480 yend
b:0 yend
aa:854190968 yend
ba:0 yend
1 голос
/ 06 мая 2011

Вам нужно инициализировать любых членов, которые есть в вашей структуре, например:

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;

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

};
0 голосов
/ 06 мая 2011

Поскольку это структура POD, вы всегда можете установить ее в 0 - это может быть самый простой способ инициализировать поля (при условии, что это уместно).

...