Не получается ошибка сегментации в C - PullRequest
2 голосов
/ 14 января 2012

вот код c:

char **s;
s[334]=strdup("test");
printf("%s\n",s[334]);`

я знаю, что strdup выполняет выделение «test», но случай s [334], где мы поместим указатель на строку «test»,однако не выделен, этот код работает как брелок

Ответы [ 5 ]

5 голосов
/ 14 января 2012

Ваш код демонстрирует неопределенное поведение. Это означает, что не означает, что он потерпит крах. Все это означает, что вы ничего не можете предсказать, что произойдет.

Сбой весьма вероятен, но не гарантирован вообще, в этом случае.

3 голосов
/ 14 января 2012

«Неопределенное поведение» не означает, что вы получите segfault, это означает, что вы можете получить segfault. Соответствующая реализация может также решить отобразить искусство ASCII щенка.

Вы можете проверить этот код с помощью инструмента, подобного Valgrind .

3 голосов
/ 14 января 2012
  1. Не всегда возникает ошибка сегментации, если вы обращаетесь к неинициализированной памяти.

  2. Вы получаете доступ к неинициализированной памяти здесь.

2 голосов
/ 14 января 2012

Компилятор слишком умен для нас! Он знает, что printf("%s\n", some_string) точно так же, как puts(some_string), поэтому он может упростить

char **s;
s[334]=strdup("test");
printf("%s\n",s[334]);

в

char **s;
s[334]=strdup("test");
puts(s[334]);

и затем (при условии отсутствия UB), что снова эквивалентно

puts(strdup("test"));

Так, случайно, ошибка сегмента не произошла (на этот раз).

2 голосов
/ 14 января 2012

Я получаю segfault без оптимизаций, но при компиляции с оптимизациями gcc вообще не беспокоится о s, он исключается как мертвый код.

gcc -Os -S:

.cfi_startproc
subq    $8, %rsp
.cfi_def_cfa_offset 16
movl    $.LC0, %edi     # .LC0 is where "test" is at
call    strdup
addq    $8, %rsp
.cfi_def_cfa_offset 8
movq    %rax, %rdi
jmp     puts
.cfi_endproc

gcc -S -O (то же самое для -O2, -O3):

.LFB23:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $5, %edi
    call    malloc
    movq    %rax, %rdi
    testq   %rax, %rax
    je      .L2
    movl    $1953719668, (%rax)
    movb    $0, 4(%rax)
.L2:
    call    puts
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
...