2009-09-07 3 views
1

У меня есть класс A следующим образом:Класс C++ массив экземпляра инициализации

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 

и Valgrind продолжает кричать о

Conditional jump or move depends on uninitialised value(s) 

и затем трассировки стека на заявления Accessors.

Может ли кто-нибудь объяснить, почему это происходит? В частности, если то, что говорит Вальгринд, верно, почему конструктор выполнен?

+0

В частности, какая строка отмечена valgrind, и какая строка говорит о ней, является источником неинициализированного значения? – mark4o

+0

Неинициализированное значение было создано распределением кучи. И он указывает на строку, которая обновила массив. – jameszhao00

+0

И какая строка была отмечена как зависящая от неинициализированного значения? – mark4o

ответ

3

Это может означать, что key или count содержит неинициализированное значение. Даже если вы инициализируете его в декларации, например. int key = foo + bar;, может быть, либо foo, либо bar неинициализирован, а valgrind переносит это на key.

+0

Спасибо за этот отзыв. Пока я просматриваю код, есть ли опция valgrind, которая показывает эти детали? – jameszhao00

+0

Поскольку вы используете --track-originins = yes, он должен сообщить вам происхождение неинициализированного значения в следующем сообщении. – mark4o

+0

Он говорит, что массив неинициализирован. – jameszhao00

2

Edit: Попробуйте установить 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 и фактическим распределением памяти в куче. Могу ли я просто предложить объединить определение и распределение в одну строку?

int count = 10; 
    A *a = new A[count]; 
+0

Вам нужно --leak-check = full --show-reachable = yes --track-originins = yes -v – jameszhao00

+0

Все еще никаких предупреждений в моей системе :) – carl

+0

Хм, странно ... но материал, который у меня выше, правильный право на инициализацию? – jameszhao00

Смежные вопросы