1

私は次のようにクラスAを持っています:

class A
{
public:    
    A()
    {        
        printf("A constructed\n");        
    }
    ~A();
    //no other constructors/assignment operators    
}

私は他の場所に次のものを持っています

A * _a;

私はそれを初期化します:

int count = ...
...
_a = new A[count];

そして私はそれにアクセスします

int key = ....
...
A *a_inst = &(_a[key]);
....

正常に実行され、コンストラクターの printf が実行され、A のすべてのフィールドが正常です。

次の引数を使用して Valgrind を実行しました。

valgrind --leak-check=full --show-reachable=yes --track-origins=yes -v ./A_app

とヴァルグリンドは叫び続けます

Conditional jump or move depends on uninitialised value(s)

次に、アクセサステートメントへのスタックトレース。

なぜこれが起こっているのか誰でも説明できますか?具体的には、Valgrind の発言が正しい場合、コンストラクターが実行されるのはなぜですか?

4

2 に答える 2

3

これは、または初期化されていない値を含むことを意味しkeyますcount。宣言で初期化したとしても、たとえば、またはが初期化されていないint key = foo + bar;可能性があり、valgrind はこれを に引き継ぎます。foobarkey

于 2009-09-07T00:48:31.687 に答える
2

編集:設定してみてくださいA *a = 0;

単純化されたシナリオでコードを実行しても、Valgrind から警告は生成されません。次のコードを検討してください。

#include <iostream>

class A
{
    public:
        A()   
        {     
            std::cout << "A" << std::endl;
        }     
};

int main()
{
    A *a; 
    int count = 10; 
    a = new A[count];

    int key = 1;
    A *inst = &(a[key]);

    return 0;
}

以下でコンパイル:

$ g++ -g main.cc -o main

そして次のように実行します:

$ valgrind --leak-check=full --show-reachable=yes --track-origins=yes ./main

ですから、もっと情報が必要だと思います。_a を定義してから実際にヒープにメモリを割り当てるまでの間に何かをしている可能性があります。定義と割り当てを 1 行にまとめていただけないでしょうか。

    int count = 10; 
    A *a = new A[count];
于 2009-09-07T00:33:54.820 に答える