2011-10-05 101 views
1

可能重复:C堆栈分配

char* arr="abc"; 
arr[0]='c'; 

您可以更改在栈上分配的字符串:
Why does this Seg Fault?

是堆栈分配是只读??

+0

http://stackoverflow.com/questions/2036096/literal-string-initializer-for-a-character-array – kan

回答

3

​​没有分配在堆栈上,它是一个字符串文字。

不,你不能修改它。您的编译器可以将该字符串放在只读内存段中(如果您的实现有这样的概念)。试图改变它导致未定义的行为。

(它崩溃的Linux上使用缺省的GCC编译实例的选项。)

7

字符串​​不是在堆栈中。指向它的指针(arr)是。修改字符串文字是未定义的行为。

您可以在ASM GCC很清楚地看到这产生于86:

 .file "test.c" 
     .section  .rodata 
.LC0: 
     .string "abc"    ; String literal inside .rodata section 
     .text 
.globl main 
     .type main, @function 
main: 
     pushl %ebp 
     movl %esp, %ebp 
     subl $16, %esp 
     movl $.LC0, -4(%ebp) ; Pointer to LC0 (our string onto stack) 
     movl -4(%ebp), %eax ; Pointer is copied into eax register 
     movb $99, (%eax)  ; Copy $99 ('c') to what eax points to (in .rodata) 
5

您的代码不会在栈上分配一个字符串。它在堆栈上分配一个char*,也就是指针,它使指针指向字符串文字。尝试修改字符串文字是未定义的行为。

要分配字符串在栈上,做到:

char arr[] = "abc"; 

现在你已经采取了串您的堆栈分配的数组arr在文本的副本,你可以修改该副本。

对于完整的步骤:我所描述的“栈分配”技术上都是“自动变量”。 C本身并不关心它们被分配的位置,但我可以猜测出你的实现确实把它们放在堆栈上。

+0

+!我几乎开始写我的回答 – Flexo

+0

但是,原始文章中没有任何内容表明这将成为自动变量,它取决于变量分配的范围。如果在文件范围内声明它,它将与其他变量一起以“静态存储持续时间”的方式结束,在RAM的某处,在某个实现定义的位置。 – Lundin

+1

@Lundin:如果提问者的代码不在函数范围内,那么'arr [0] ='c';'绝对不允许。 –