【发布时间】:2011-12-01 08:22:51
【问题描述】:
【问题讨论】:
标签: c stack memory-management
【问题讨论】:
标签: c stack memory-management
字符串"abc" 不在堆栈中。指向它的指针 (arr) 是。修改字符串文字是未定义的行为。
您可以在 GCC 在 x86 上生成的 asm 中非常清楚地看到这一点:
.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)
【讨论】:
您的代码没有在堆栈上分配字符串。它在堆栈上分配一个char*,也就是说一个指针,它使该指针指向一个字符串字面量。尝试修改字符串文字是未定义的行为。
要在堆栈上分配字符串,请执行以下操作:
char arr[] = "abc";
现在您已经在堆栈分配的数组arr 中获取了字符串文字的副本,并且您可以修改该副本。
完全学究气:我所说的“堆栈分配”在技术上都是“自动变量”。 C 本身并不关心它们的分配位置,但我可以很有信心地猜测您的实现实际上确实将它们放在了堆栈上。
【讨论】:
arr[0] = 'c';肯定是不允许的。
"abc" 没有在栈上分配,它是一个字符串字面量。
不,您不能修改它。您的编译器可以将该字符串放在只读内存段中(如果您的实现有这样的概念)。试图改变它会导致未定义的行为。
(它在带有默认编译选项的 GCC 的 Linux 上崩溃。)
【讨论】: