Наш код включает структуру POD (Plain Old Datastructure) (это базовая структура C ++, в которой есть другие структуры и переменные POD, которые необходимо инициализировать вначале).
Судя по тому, что я читал , кажется, что:
myStruct = (MyStruct*)calloc(1, sizeof(MyStruct));
должен инициализировать все значения до нуля, как это делает:
myStruct = new MyStruct();
Однако, когда структура инициализируется вторым способом, Valgrind позже жалуется, что "условный переход или перемещение зависят от неинициализированного значения (значений)" при использовании этих переменных. Мое понимание здесь ошибочно, или Valgrind выдает ложные срабатывания?
new MyStruct()
не требуется устанавливать какие-либо байты заполнения в C ++ 03. В C ++ 0x это так. Любые биты заполнения будут установлены в 0 в C ++ 0x.Ответы:
В 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();
Быстрый поиск по «самому неприятному синтаксическому анализу» даст лучшее объяснение, чем я.
источник
C()
но похоже ты прав .T
,T()
всегда равна нулю инициализирован скалярные подобъектов. Имя инициализации верхнего уровня в C ++ 98 называлось иначе, чем в C ++ 03 («инициализация по умолчанию» и «инициализация значения»), но конечный эффект для POD такой же. И в C ++ 98, и в C ++ 03 все значения будут равны нулю.C c();
к сожалению, не является объявлением переменной, а скорее предварительным объявлением функции (функция с именем 'c', которая не принимает параметров и возвращает объект типа C). Google: Самый неприятный синтаксический анализC c(4);
Действительное объявление переменной.Судя по тому, что вы нам сказали, в valgrind это действительно ложное срабатывание.
new
Синтаксис с()
, дорожа инициализировать объект, при условии , что это СТРУЧОК.Возможно ли, что какая-то часть вашей структуры на самом деле не POD, и это препятствует ожидаемой инициализации? Можете ли вы упростить свой код и превратить его в пример для публикации, который по-прежнему указывает на ошибку valgrind?
В качестве альтернативы, возможно, ваш компилятор на самом деле не инициализирует структуры POD значениями.
В любом случае, вероятно, самое простое решение - написать конструктор (ы), необходимый для структуры / подразделов.
источник
Я пишу тестовый код:
#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
источник
new sc;
противnew sc();
. Я бы подумал, что отсутствующие скобки были ошибкой. Но это, кажется, демонстрирует, что ответ правильный (он выполняет инициализацию до 0, когда вы используете конструктор по умолчанию.)Вам необходимо инициализировать все члены вашей структуры, например:
struct MyStruct { private: int someInt_; float someFloat_; public: MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values };
источник
Поскольку это структура POD, вы всегда можете установить ее в значение 0 - это может быть самый простой способ инициализировать поля (при условии, что это уместно).
источник
Это кажется мне самым простым способом. Члены структуры могут быть инициализированы с помощью фигурных скобок '{}'. Например, ниже приведена действительная инициализация.
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}; }
Есть хорошая информация о структурах в c ++ - https://www.geeksforgeeks.org/structures-in-cpp/
источник