Valgrind Сравнение указателя с NULL - PullRequest
0 голосов
/ 26 июня 2018

Я использую Valgrind для отладки своего кода и получаю предупреждение, когда проверяю, инициализируется ли struct, сравнивая его с NULL.

void main()
{
    int *unassignedPointer;
    if(unassignedPointer == NULL)
        printf("This Pointer is NULL\n");
}

Этот код компилируется и запускается, но при запуске через Valgrind выдает предупреждение: условный переход или перемещение зависит от неинициализированных значений. Весь смысл сравнения с NULL состоит в том, чтобы определить, инициализирован он или нет. Это опасная практика, или я должен просто игнорировать эти предупреждения?

Ответы [ 4 ]

0 голосов
/ 26 июня 2018

Когда переменная неинициализирована, это означает, что ей не было явно задано начальное значение. Это означает, что оно может иметь любое значение, включая NULL или другое значение.

Формально неинициализированная переменная, которая не имеет статической длительности хранения (т. Е. Локальная переменная, не помеченная static), имеет неопределенное значение.

Также, как правило, предупреждения в C не должны никогда игнорироваться. Язык предполагает, что вы знаете, что делаете, и не имеет никаких средств защиты, которые есть у другого языка.

0 голосов
/ 26 июня 2018

unassignedPointer является унитарной локальной переменной, и чтение такой переменной приведет к неопределенному поведению, то есть вы никогда не будете знать, что произойдет. На большинстве архитектур эти переменные будут просто содержать мусор в памяти, и ваш код ничего не напечатает или «Этот указатель равен NULL» в зависимости от вашей удачи. Вы должны правильно инициализировать переменную:

void main()
{
  int *unassignedPointer = NULL;
  if(unassignedPointer == NULL)
  printf("This Pointer is NULL\n");
}
0 голосов
/ 26 июня 2018

Сначала здесь

int *unassignedPointer; /*here it can points to any unknown memory location */ 

unassignedPointer не инициализируется и не указывает на правильное расположение в памяти, а разыменование (если вы пытались) приводит к неопределенному поведению. ваш компилятор может предупредить вас как

ass unassignedPointer ’используется неинициализированным в этой функции [-Werror = неинициализированным]

, если вы скомпилировали свой код с соответствующим флагом предупреждения, таким как -Wall и т. Д., Поэтому сначала инициализируйте unassignedPointer с помощью NULL, как

int *unassignedPointer = NULL;

Это опасная практика, или я должен просто игнорировать эти предупреждения? никогда не следует игнорировать предупреждение компилятора. Лучше скомпилировать любой простой код с помощью

gcc -Wall -Wstrict-prototypes -Werror test.c   /* Werror, stops the compilation, convert warning into error */ 

Также читайте C языковой стандарт, черновик n1256 раздел 5.1.2.2.1

Запуск программы: Он должен быть определен с типом возврата int и без параметров:

int main(void) { /*
...
*/ }

или с двумя параметрами (здесь упоминаются как argc и argv, хотя Можно использовать Ames, так как вы локальны для функции, в которой ты объявлен):

int main(int argc, char *argv[]) { /*
...
*/ }

Это

void main() { 
   /*some code */
}

не правильно, вместо этого используйте

int main(void) {
    /*some code */
}
0 голосов
/ 26 июня 2018

Вы, конечно, не должны игнорировать предупреждение, вы должны исправить его, инициализируя указатель:

int *pointer = NULL;

в общем случае вы не можете определить, была ли назначена переменная, нет волшебного значения «нет значения», все биты переменной используются для хранения фактического значения.

...