内存分配本地初始化字符串数组

时间:2012-08-01 06:45:39

标签: c variables memory memory-management initialization

假设,我写了一个函数如下:

void foo()
{
   char *strArr[] = {"AA", "BB", "CC"};
   ...
}

strArr将被分配到哪里?什么时候会被初始化?

出于某种原因,我记得这样的数组将被分配在静态存储空间中,而不是在堆栈上并在程序启动时初始化,就好像我会在它之前编写“静态”一样。这是假记忆吗?

3 个答案:

答案 0 :(得分:5)

它具有自动存储功能,因此它将被分配在该功能的堆栈中。这些元素属于这个自动存储,但字符串文字本身存储在一个持久的,可能只读的区域中。

答案 1 :(得分:3)

数组将被分配为本地对象。在一般情况下,当函数开始执行时,可以提前分配所有本地对象的内存,或者可以“按需”分配所有本地对象的内存,因为控件使用对象声明进入嵌套块。该语言没有指定确切的时刻。

在您的具体示例中,当函数开始执行时,将分配数组的内存,因为您的数组是在函数的“主”块中声明的。

至于初始化...在C89 / 90版本的C中,所有聚合初始化器必须是常量表达式,这意味着聚合初始化过程不能依赖于任何运行时值。初始化可以硬编码到已编译的程序中,并且可以在分配数组后立即进行。

在C99中,您可以在聚合初始值设定项中使用运行时值,这意味着实际的初始化可能必须延迟到控制权超过声明时的点。

在您的示例中,数组使用常量表达式初始化,这意味着它可以在分配后立即初始化。编译器实际上可以提前准备一个数组的静态副本,并在每次控件进入函数时将其“粘贴”到堆栈中。

P.S。您对“静态内存”的引用实际上适用于您用于初始化数组元素的字符串文字(如"AA")。字符串文字确实驻留在静态内存中。但是,字符串文字是完全独立的对象,而strArr数组是完全独立的对象。

请注意,您的示例中没有“字符串数组”。你拥有的是一系列指针到字符串。您的strArr位于本地内存中,而字符串(strArr指向哪些元素)位于静态内存中。

答案 2 :(得分:1)

我刚刚反汇编了一个示例程序。

#include <stdio.h>
void foo()
{
   char *strArr[] = {"AA", "BB", "CC"};
}

int main()
{
foo();
return 0;
}

看来,字符串文字将在.rodata部分中分配。

 .file   "sfsfs.c"
        .section        .rodata
.LC0:
        .string "AA"
.LC1:
        .string "BB"
.LC2:
        .string "CC"
        .text
        .globl  foo
        .type   foo, @function
foo:
.LFB0:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        .....
        .....    

但是strArr只会在堆栈中分配。因为它是自动性的。