97

このコードには、POD(Plain Old Datastructure)構造体が含まれています(これは、最初に初期化する必要がある他の構造体とPOD変数を含む基本的なc ++構造体です)。

私が読んだものに基づいて、それは次のようです:

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

次のように、すべての値をゼロに初期化する必要があります。

myStruct = new MyStruct();

ただし、構造体が2番目の方法で初期化されると、Valgrindは、これらの変数が使用されると、後で「条件付きジャンプまたは移動は初期化されていない値に依存する」と文句を言います。私の理解はここで欠陥がありますか、それともValgrindは誤検知を投げていますか?

4

6 に答える 6

140

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();

「MostVexingParse」をすばやく検索すると、私よりもわかりやすい説明が得られます。

于 2011-05-06T17:02:29.937 に答える
2

あなたが私たちに言ったことから、それはvalgrindの誤検知であるように見えます。のnew構文()は、PODであると想定して、オブジェクトの値を初期化します。

構造体の一部が実際にはPODでなく、それが予期された初期化を妨げている可能性はありますか?コードを単純化して、valgrindエラーにフラグを立てる投稿可能な例にすることはできますか?

あるいは、コンパイラが実際にPOD構造を値初期化しない場合もあります。

いずれにせよ、おそらく最も簡単な解決策は、構造体/サブパーツの必要に応じてコンストラクターを作成することです。

于 2011-05-06T17:06:55.733 に答える
1

私はいくつかのテストコードを書きます:

#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
于 2017-01-21T01:25:36.760 に答える
0

これはPOD構造体であるため、いつでも0にmemsetできます。これは、フィールドを初期化する最も簡単な方法である可能性があります(適切であると想定)。

于 2011-05-06T16:42:27.140 に答える
0

構造体にあるメンバーを初期化する必要があります。例:

struct MyStruct {
  private:
    int someInt_;
    float someFloat_;

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

};
于 2011-05-06T16:45:49.330 に答える
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/

于 2020-01-26T20:14:20.383 に答える