【问题标题】:C Stack allocation [duplicate]C堆栈分配[重复]
【发布时间】:2011-12-01 08:22:51
【问题描述】:

可能重复:
Why does this Seg Fault?

栈分配是否为只读:

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

你能改变分配在堆栈上的字符串吗??

【问题讨论】:

标签: c stack memory-management


【解决方案1】:

字符串"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)

【讨论】:

    【解决方案2】:

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

    要在堆栈上分配字符串,请执行以下操作:

    char arr[] = "abc";
    

    现在您已经在堆栈分配的数组arr 中获取了字符串文字的副本,并且您可以修改该副本。

    完全学究气:我所说的“堆栈分配”在技术上都是“自动变量”。 C 本身并不关心它们的分配位置,但我可以很有信心地猜测您的实现实际上确实将它们放在了堆栈上。

    【讨论】:

    • +!对于迂腐,我几乎开始写我的答案
    • 但是,原帖中没有任何内容表明这将成为一个自动变量,这取决于变量分配在什么范围内。如果在文件范围内声明,它将结束与其他具有“静态存储持续时间”的变量一起,位于 RAM 中某个实现定义的位置。
    • @Lundin:如果提问者的代码不在函数范围内,那么arr[0] = 'c';肯定是不允许的。
    • @Steve Well... 没有什么说这两个源代码行位于彼此之后:) 但是点。顺便说一句,因为我们处于完全迂腐的土地上,我认为你的意思是块范围。标准定义的函数范围仅适用于 goto-labels :)
    • @Lundin:好的,我会相信你的话而不检查:-)
    【解决方案3】:

    "abc" 没有在栈上分配,它是一个字符串字面量。

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

    (它在带有默认编译选项的 GCC 的 Linux 上崩溃。)

    【讨论】:

      猜你喜欢
      • 2016-04-25
      • 1970-01-01
      • 2012-07-19
      • 2018-06-29
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2017-12-23
      • 2011-04-13
      相关资源
      最近更新 更多