Интерпретация ошибки valgrind

Я пытаюсь отладить свой код с помощью valgrind. Большинство сообщений, которые я получаю, таковы:

Conditional jump or move depends on uninitialised value(s)

or

Invalid read of size 8

Меня в основном беспокоит первое: если бы значение было действительно неинициализированным, я полагаю, что произойдет ошибка сегментации. Я проверил это, отправив тот же указатель на другую функцию вместе с неинициализированным указателем на функцию, которая, как я знаю, вызывает ошибку сегментации, и только действительно неинициализированный указатель вызывает ошибку сегментации.

Что также может означать это сообщение об ошибке.

Кроме того, что означает вторая ошибка?

Edit1
Вот код модели, выдаст ли он ошибку 1 (предположим, что файлы заголовков допустимы)?

a.cpp

B b;
C c;
int main(){
  return 0;
}

B.cpp

extern C c;
//    double t; //canceld, declared in the header.
B::B(){
  this->t = 1;
  c.test(t);
}
B::test(){
  c.test(this->t);
}

B.cpp

C::C(){
}

C::test(double t){
  printf("%f\n",t);
}

person Yotam    schedule 01.08.2011    source источник
comment
Указывает ли valgrind на определенные строки кода? Было бы полезно увидеть несколько примеров кода, который он помечает. Первый может не обязательно иметь отношение к указателям, но может быть любой переменной, которую вы не инициализируете, но затем используете в условном выражении.   -  person Eugene S    schedule 01.08.2011
comment
Мой опыт работы с valgrind заключался в том, что когда он указывает на ошибку, а я не вижу ее, я просто неправильно понимаю ошибку и / или код, и valgrind был на самом деле прав.   -  person Mark B    schedule 01.08.2011
comment
@unluddite, да, это так. Прежде чем я вставлю это в свой код, возможно ли, что это сообщение выдается, потому что функция, которую я использую для переданного указателя, действительно принадлежит классу, который инициализируется после того, как я вызываю функцию? (Я поставил псевдокод модели в свой вопрос)   -  person Yotam    schedule 01.08.2011
comment
@Mark B, это соответствует моему редактированию и комментарию. У меня вопрос, как понять эти ошибки.   -  person Yotam    schedule 01.08.2011
comment
@Yotam - Если вы вызовете test() из конструктора B, это будет проблемой. В противном случае это больше похоже на то, что у вас есть if (x > 5), где x не имеет значения. Это не будет проблемой.   -  person Bo Persson    schedule 01.08.2011
comment
@Bo Persson, я отредактировал свой псевдокод, как мне кажется, в соответствии с моим настоящим кодом. Есть ли способ заставить valgrind игнорировать эту ошибку? в этом случае программа не вылетает.   -  person Yotam    schedule 01.08.2011
comment
Я не понимаю t здесь. Похоже, что это часть B, но объявлена ​​как свободная переменная в b.cpp. Бесплатная переменная - всего лишь отвлекающий маневр?   -  person daramarak    schedule 01.08.2011
comment
@Yotam - объекты в a.cpp инициализируются в порядке их появления. Вызов любой функции на c до запуска ее конструктора является ошибкой. Если конструктор пуст, он все равно может работать, но это все равно ошибка.   -  person Bo Persson    schedule 01.08.2011
comment
@daramarak, теперь моя правка имеет смысл?   -  person Yotam    schedule 01.08.2011
comment
@Bo Persson, поэтому, если мне нужна функция из класса, который имеет быть объявленным только после функции, из которой мне нужен класс (предположим, что C нужно что-то из B в моем примере). Мне нужно создать для этого дополнительный класс / функцию?   -  person Yotam    schedule 01.08.2011
comment
@Yotam Я по крайней мере понимаю, что вы имеете в виду. Но я бы предпочел исполняемый код, который выдает описанные вами ошибки valgrind. В этом примере у вас проблема. получить проблемы с использованием c до того, как он будет инициализирован и выделен.   -  person daramarak    schedule 02.08.2011


Ответы (1)


Conditional jump or move depends on uninitialised value(s)

Это означает, что вы пытаетесь что-то сделать с неинициализированной переменной. Например:

int main()
{
    int x;
    if (x == 5)
        printf("%d\n", x);
    return 0;
}

должен сделать свое дело. Вы не можете сравнить / распечатать или что-то сделать с неинициализированной переменной.

Invalid read of size 8

Это означает, что вы пытаетесь читать из памяти, которой нет, то есть не было выделено.

int main()
{
    char* x = malloc(10);
    x[10] = '@';    //this is an invalid write
    printf("%c\n", x[10]); //this is an invalid read
    return 0;
}

Это вызовет ошибку, потому что вы выделили место только для 10 символов, но вы пишете / читаете 11-й символ (помните, что массивы индексированы 0, поэтому вы можете писать только до 0-9).

«размер X» - это объем памяти, который вы пытаетесь прочитать, поэтому размер 8 означает, что вы пытаетесь прочитать 8 байтов.

Надеюсь, это поможет. Разместите более конкретный код, если вам нужна помощь по отладке. Valgrind обычно сообщает вам, где возникает ошибка, чтобы вы могли понять, что делать.

person BlackJack    schedule 01.08.2011
comment
В этом случае мы можем предположить, что двойное значение будет 8 байтов. - person Bo Persson; 01.08.2011
comment
Спасибо, проблема в том, что в обоих случаях код компилируется (неудивительно) и запускается (неожиданно) через эти ошибки, насколько я могу судить, причиной ошибки является класс, который я использую для запуска функции, а не элементом, который я передаю функции. Моя настоящая ошибка сегментации вызвана совершенно другими вещами, и я хочу сначала разобраться с ошибками нежелательной почты. - person Yotam; 01.08.2011
comment
@ Yotam - Вероятно, это элемент, который вы проходите. Часто valgrind сообщает, что ошибка вызвана функцией foo() в классе bar, тогда как на самом деле это параметр, который вы передаете в foo, который вызывает ошибку. Если бы вы могли опубликовать код, мы могли бы помочь вам гораздо больше. - person BlackJack; 01.08.2011
comment
@BlackJack, я знаю, что элемент, который я передаю, действителен (я это проверил). - person Yotam; 02.08.2011