没有在C中获得分段错误

时间:2012-01-14 11:13:28

标签: c segmentation-fault

这是c代码:

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

我知道strdup会分配“test”,但是我们将把指针放到字符串“test”的情况下[334]没有分配,但是,这段代码就像魅力一样

5 个答案:

答案 0 :(得分:5)

您的代码显示未定义的行为。那意味着它会崩溃。这意味着你无法预测会发生什么。

崩溃很可能,但在这种情况下根本不能保证。

答案 1 :(得分:3)

  1. 如果访问未初始化的内存,则不会总是出现分段错误。

  2. 您可以在此处访问未初始化的内存。

答案 2 :(得分:3)

“未定义的行为”并不意味着您将获得段错误,这意味着您可能会遇到段错误。符合标准的实现也可能决定显示小狗的ASCII艺术。

您可能希望使用Valgrind等工具检查此代码。

答案 3 :(得分:2)

我得到了一个没有优化的段错误,但是当使用优化进行编译时,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

答案 4 :(得分:2)

编译器对我们来说太聪明了!它知道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"));

因此,偶然发生了段故障(此时)。