Что такое поведение компилятора C при указании на отрицательный адрес памяти? - PullRequest
0 голосов
/ 02 декабря 2018

Каково состояние p1, p2 после компиляции и запуска под кодом фрагмента C?

char *p1 = malloc(5);
char *p2 = p1 - 3;
*p2 = '\0';

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Если бы вы превращали этот код C непосредственно в простой машинный код на простой машине, то char *p2 = p1 - 3; установит p2 для указания на три байта в памяти раньше, чем p1, а *p2 = '\0' будет записывать нольв неподходящее место.Мы не знаем, что находится в этом месте, поэтому мы не можем сказать, каков эффект.

Однако современные компиляторы обычно не превращают код C непосредственно в простой машинный код.Они интерпретируют код C и выполняют сложные оптимизации на нем.Поэтому для понимания того, что происходит, необходимо использовать стандарт C или документацию для используемого компилятора.

Что стандарт C говорит нам об этом коде?Для p1 - 3 применяются правила добавления с указателем в C 2018 6.5.6 8:

Когда выражение с целочисленным типом добавляется или вычитается из указателя,… Если обаоперанд указателя и результат указывают на элементы одного и того же объекта массива или одного элемента после последнего элемента объекта массива, оценка не должна вызывать переполнение;в противном случае поведение не определено.

Поскольку p1 указывает на элемент объекта (который может использоваться в качестве массива), предоставленный malloc, а p1 - 3 не указывает наэлемент этого массива, поведение не определяется стандартом C.Поэтому, если мы используем стандарт C в качестве основы для понимания, после оценки p1 - 3 мы не можем сказать, каково поведение программы или состояние p1 и p2.

0 голосов
/ 02 декабря 2018

p1 указывает на начало выделенного блока памяти.p2 содержит адрес байта за три байта до этого блока.Таким образом, третья строка будет изменять байт за пределами блока памяти, который будет либо перезаписывать некоторые данные, выделенные другим кодом, либо повреждать структуры управления памятью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...