Valgrind Сравнение указателя с NULL
Я использую Valgrind для отладки своего кода и получаю предупреждение, когда проверяю, struct
инициализируется путем сравнения его с NULL
,
void main()
{
int *unassignedPointer;
if(unassignedPointer == NULL)
printf("This Pointer is NULL\n");
}
Этот код компилируется и запускается, но при запуске через Valgrind выдает предупреждение: условный переход или перемещение зависит от неинициализированных значений. Весь смысл сравнения с NULL
определить, инициализирован ли он или нет. Это опасная практика, или я должен просто игнорировать эти предупреждения?
4 ответа
Конечно, вы не должны игнорировать предупреждение, вы должны исправить его, инициализируя указатель:
int *pointer = NULL;
как правило, вы не можете определить, была ли назначена переменная, нет волшебного значения "нет значения", все биты переменной используются для хранения действительного значения.
unassignedPointer является унитарной локальной переменной, и чтение такой переменной приведет к неопределенному поведению, то есть вы никогда не будете знать, что произойдет. На большинстве архитектур эти переменные будут просто содержать мусор в памяти, и ваш код ничего не напечатает или "Этот указатель равен NULL" в зависимости от вашей удачи. Вы должны правильно инициализировать переменную:
void main()
{
int *unassignedPointer = NULL;
if(unassignedPointer == NULL)
printf("This Pointer is NULL\n");
}
Во первых здесь
int *unassignedPointer; /*here it can points to any unknown memory location */
unassignedPointer
не инициализируется и не указывает на правильное расположение в памяти и разыменование (если вы пытались), это вызывает неопределенное поведение. ваш компилятор может предупредить вас как
unassignedPointer используется неинициализированным в этой функции [-Werror=uninitialized]
если вы скомпилировали свой код с соответствующим флагом предупреждения, как -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, хотя можно использовать yn ames, поскольку вы локальны для функции, в которой вы объявили):
int main(int argc, char *argv[]) { /* ... */ }
это
void main() {
/*some code */
}
не правильно, вместо этого используйте
int main(void) {
/*some code */
}
Когда переменная неинициализирована, это означает, что ей не было задано начальное значение. Это означает, что он может иметь любое значение, включая NULL или какое-либо другое значение.
Формально, неинициализированная переменная, которая не имеет статической длительности хранения (т.е. локальная переменная не помечена static
) имеет неопределенное значение.
Также, как правило, предупреждения в C никогда не следует игнорировать. Язык предполагает, что вы знаете, что делаете, и не имеет никаких средств защиты, которые есть у другого языка.