このコードには、POD(Plain Old Datastructure)構造体が含まれています(これは、最初に初期化する必要がある他の構造体とPOD変数を持つ基本的なc ++構造体です)。
私が持っているものの1つに基づいて 読み取り 、それはそうです:
myStruct = (MyStruct*)calloc(1, sizeof(MyStruct));
次のように、すべての値をゼロに初期化する必要があります。
myStruct = new MyStruct();
ただし、構造体が2番目の方法で初期化されると、Valgrindは、それらの変数が使用されると「条件付きジャンプまたは移動は初期化されていない値に依存する」と後で訴えます。ここで私の理解に欠陥がありますか、またはValgrindは誤検知を投げかけていますか?
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」をすばやく検索すると、説明よりも優れた説明が得られます。
あなたが私たちに言ったことから、それはvalgrindで偽陽性であるように見えます。 ()
を含むnew
構文は、オブジェクトがPODであると仮定して、値を初期化する必要があります。
構造体の一部が実際には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
これはPOD構造体なので、常に0にmemsetすることができます-これは、フィールドが初期化される最も簡単な方法かもしれません(適切であると仮定)。
構造体にあるメンバーを初期化する必要があります。例:
struct MyStruct {
private:
int someInt_;
float someFloat_;
public:
MyStruct(): someInt_(0), someFloat_(1.0) {} // Initializer list will set appropriate values
};