可能重复:
Program crashes when trying to set a character of a char array字符*海峡= “...” 与字符STR [1] = “...” 奇怪的行为
我有一个示例代码工作预期:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
/*
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
*/
return 0;
}
...除非我改变字符STR [1]为char *海峡不应使任何语义差异:
/* strtok example */
#include <stdio.h>
#include <string.h>
int main()
{
char * str ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
/*
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
*/
return 0;
}
这是意想不到的结果:
Splitting string "- This, a sample string." into tokens:
Segmentation fault
我编译两个例子:
gcc -O0 main.c
gcc -O3 main.c
g++ -O0 main.c
g++ -O3 main.c
,甚至看着组装......但我无法弄清楚,什么是第二个版本错误。
这里工作O1-大会:
.file "main.c"
.intel_syntax noprefix
.section .rodata.str1.8,"aMS",@progbits,1
.align 8
.LC0:
.string "Splitting string \"%s\" into tokens:\n"
.section .rodata.str1.1,"aMS",@progbits,1
.LC1:
.string " ,.-"
.text
.globl main
.type main, @function
main:
.LFB58:
.cfi_startproc
push rbx
.cfi_def_cfa_offset 16
sub rsp, 48
.cfi_def_cfa_offset 64
mov rax, QWORD PTR fs:40
mov QWORD PTR [rsp+40], rax
xor eax, eax
mov DWORD PTR [rsp], 1750343725
mov DWORD PTR [rsp+4], 539784041
mov DWORD PTR [rsp+8], 1634934881
mov DWORD PTR [rsp+12], 1701605485
mov DWORD PTR [rsp+16], 1920234272
mov DWORD PTR [rsp+20], 778530409
mov BYTE PTR [rsp+24], 0
mov rdx, rsp
mov esi, OFFSET FLAT:.LC0
mov edi, 1
.cfi_offset 3, -16
call __printf_chk
mov esi, OFFSET FLAT:.LC1
mov rdi, rsp
call strtok
mov eax, 0
mov rdx, QWORD PTR [rsp+40]
xor rdx, QWORD PTR fs:40
je .L3
call __stack_chk_fail
.L3:
add rsp, 48
pop rbx
.p2align 4,,1
ret
.cfi_endproc
.LFE58:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
和破一个:
.file "main.c"
.intel_syntax noprefix
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "- This, a sample string."
.section .rodata.str1.8,"aMS",@progbits,1
.align 8
.LC1:
.string "Splitting string \"%s\" into tokens:\n"
.section .rodata.str1.1
.LC2:
.string " ,.-"
.text
.globl main
.type main, @function
main:
.LFB58:
.cfi_startproc
sub rsp, 8
.cfi_def_cfa_offset 16
mov edx, OFFSET FLAT:.LC0
mov esi, OFFSET FLAT:.LC1
mov edi, 1
mov eax, 0
call __printf_chk
mov esi, OFFSET FLAT:.LC2
mov edi, OFFSET FLAT:.LC0
call strtok
mov eax, 0
add rsp, 8
ret
.cfi_endproc
.LFE58:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5"
.section .note.GNU-stack,"",@progbits
唯一明显的区别,我可以看到的是,在工作版本的GCC替换字符串用的MOV不变直接在代码中。
帮助是非常赞赏
编辑 GCC(Ubuntu的/ Linaro的4.4.4-14ubuntu5)4.4.5,
一切顺利, 托马斯
嗯...你是否搜索这个问题了?现在至少问了5次... – quasiverse
请阅读[c-faq](http://c-faq.com/)的第6部分。基本上它说**数组不是指针**和**指针不是数组**。因为你已经在那里,请阅读其他章节:) – pmg
请确定一种语言。 C和C++是不同的语言。 –