Почему это не Segfault - PullRequest
4 голосов
/ 13 июля 2010

Я наткнулся на что-то «интересное» и не могу понять, почему поведение не связно.

Проверьте этот код.

char buf[100];
sprint(buf,"%s",bla);

Просто, верно. Легко понять, что происходит, когда bla является указателем NULL.

Это всегда должно быть segfault, верно!?

На одном компьютере исполняемые ошибки segfaults, на другом (мой компьютер для разработки), это просто обычный бизнес.

Мой ПК с devel работает Windows7, и я компилирую с gcc/MingW. Компьютер, на котором происходит сбой, - XP, и на нем установлен Visual studio 6.

Почему это не происходит на моем ПК?

Ответы [ 6 ]

24 голосов
/ 13 июля 2010

ISO C99: 7.19.6.3 The printf function

Конспект

 #include <stdio.h>
 int printf(const char * restrict format, ...);

The printf function is equivalent to fprintf with the argument stdout interposed before the arguments to printf.

7.19.6.1 The fprintf function

7.19.6.1.9

If a conversion specification is invalid, the behavior is **undefined**. If any argument is not the correct type for the corresponding conversion specification, the behavior is **undefined**.

Таким образом, ваш код вызывает Неопределенное поведение [(ISO C99 3.4.3) behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes **no requirements**]

Это всегда должно быть segfault правильно!?

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

11 голосов
/ 13 июля 2010

Это всегда должно быть segfault, верно!?

Нет. Это вызывает неопределенное поведение . Ошибка сегментации - лишь один из многих возможных результатов вызова UB.

3 голосов
/ 13 июля 2010

Поскольку печать нулевой ссылки в виде строки (насколько я знаю, не проверено стандартами) не определена.Многие системы просто выводят (null) в результате.

То же самое с другими функциями printf:

printf ("%s", NULL); // Outputs (null) to the console on some systems but can crash others
1 голос
/ 13 июля 2010

Это всегда должно быть segfault, верно!?

Нет. Это зависит от реализации функции sprintf, поставляемой со стандартной библиотекой компилятора.

Насколько я знаю, в спецификации sprintf не указано, что вы должны указывать ненулевой адрес.

1 голос
/ 13 июля 2010

Кроме того, segfault никогда не гарантируется.Если это происходит, где-то есть ошибка;но наличие ошибки где-то не влечет за собой segfault.

0 голосов
/ 13 июля 2010

Все зависит от того, на что указывает бла в то время. Функция sprintf () будет копировать все символы, на которые указывает bla, до тех пор, пока он не встретит нулевой (0x00) символ.

Если он встречает нулевой символ до того, как достигнет предела buf [100], тогда нет никакого segfault, потому что мы не пишем сверх предела buf.

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

...