Итак, строка кода, о которой идет речь, это:
*((int*)(0))=1;
Поскольку у меня так мало опыта работы с C/С++ и я не очень старался, я не понимаю этого простого выражения. Что это значит?
Итак, строка кода, о которой идет речь, это:
*((int*)(0))=1;
Поскольку у меня так мало опыта работы с C/С++ и я не очень старался, я не понимаю этого простого выражения. Что это значит?
Это означало сбой программы, обычно полезный при отладке.
Это приведет к разыменованию указателя NULL и попытке присвоить значение этой памяти, что теоретически просто поведение undefined, но приведет к исключению нарушения доступа на 99% систем.
Обычно он обнаруживается в таких случаях, как:
if ( !FileRead(importantFile) )
{
// this should never happen, critical exception
*((int*)(0))=1;
}
Разбивайте его по частям. Внутри внешних кронштейнов слева у вас есть:
(int*)(0)
Это C-стиль, содержащий значение 0 для указателя на int; создавая нулевой указатель, по сути.
Добавьте добавление переменной, чтобы зафиксировать результат этого первого выражения:
int* x = (int*)(0);
Внешняя часть теперь:
*(x) = 1;
Это разыменование указателя x и присвоение 1 полученному int.
Так как (в этом случае) x является нулевым указателем, это приведет к сбою при разыменовании (строго говоря, он будет разбиваться на присваивание после разыменования - см. комментарии ниже). Он обычно используется для принудительного сбоя или другого зависящего от системы поведения undefined; обычно для тестирования или отладки. Вам не нужна такая строка в вашем производственном коде.
Примечание. Существуют некоторые архитектуры, как правило, во встроенных системах, где нуль является допустимым адресом памяти, а приведенный выше код может иметь законную цель. Однако, если вы работаете на такой платформе, вряд ли вам придется бороться с синтаксисом в вопросе.
Как отмечали другие, это способ попасть в отладчик. Большинство компьютеров откажутся записывать в адрес памяти 0
и вместо этого введут какой-то диагностический режим.
Однако лучшей альтернативой является стандартная функция raise()
, от <signal.h>
или <csignal>
. raise( SIGSEGV )
даст тот же результат, что и ваш пример, даже на компьютерах, которые позволяют записывать нулевые адреса (такие машины существуют!) и компиляторы с либеральной интерпретацией поведения undefined. Эта операция не гарантируется или не требуется для сбоя. С точки зрения компилятора он также может ничего не делать, и было бы неверно просто удалить его из скомпилированной программы.
Для более описательного значения сигнала см. man signal
. То, что имеется в виду, возможно, это raise( SIGTRAP )
или abort()
. Последнее эквивалентно raise( SIGABRT )
в моей системе, но я ленив, чтобы проверить, гарантирована ли эта эквивалентность с помощью POSIX или языка C.
Это хранит что-то с нулевым указателем (и вызывает SEGFAULT). Полезно для остановки программы и вызова отладчика, сохраняя при этом все содержимое памяти и т.д.
Этот *((int*)(0))=1;
равен
int *p=NULL;
*p=1;