没有在C中获得分段错误
这是c代码:
char **s; s[334]=strdup("test"); printf("%s\n",s[334]);`
我知道strdup会分配“test”,但是我们将把指针放到字符串“test”的情况下[334]没有分配,但是,这个代码就像一个魅力
编译器对我们来说太聪明了! 它知道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"));
因此,偶然发生了段故障(此时)。
您的代码显示未定义的行为。 这并不意味着它会崩溃。 这意味着你无法预测会发生什么。
在这种情况下,崩溃很可能,但根本无法保证。
“未定义的行为”并不意味着您将获得段错误,这意味着您可能会遇到段错误。 符合标准的实现也可能决定显示小狗的ASCII艺术。
您可能希望使用Valgrind之类的工具来检查此代码。
-
如果访问未初始化的内存,则不会总是出现分段错误。
-
你可以在这里访问未初始化的内存。
我得到了一个没有优化的段错误,但是当用优化编译时,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