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

C 本地初始化字符串数组的内存分配,c,variables,memory,memory-management,initialization,C,Variables,Memory,Memory Management,Initialization,假设,我编写了一个函数,如下所示: void foo() { char *strArr[] = {"AA", "BB", "CC"}; ... } strArr将在哪里分配?什么时候初始化 出于某种原因,我记得这样一个数组将在静态内存空间中分配,而不是在堆栈上,并在程序启动时初始化,就好像我会在它前面写“static”。它是假的内存吗?它具有自动存储功能,因此将在函数堆栈上进行分配。元素属于此自动存储,但字符串文本本身存储在一个持久的、可能是只读的区域中。数组将作为本地对象分配。在

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

void foo()
{
   char *strArr[] = {"AA", "BB", "CC"};
   ...
}
strArr将在哪里分配?什么时候初始化


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

它具有自动存储功能,因此将在函数堆栈上进行分配。元素属于此自动存储,但字符串文本本身存储在一个持久的、可能是只读的区域中。

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

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

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

在C99中,可以在聚合初始值设定项中使用运行时值,这意味着实际初始化可能必须延迟到控件传递声明时

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

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


请注意,在您的示例中并没有真正的“字符串数组”。您拥有的是一个指向字符串的指针数组。您的
strArr
存在于本地内存中,而字符串(strArr的元素指向)存在于静态内存中。

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

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

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

但strArr将仅在堆栈中分配。因为这是天生的

这些元素是指向字符串文字的第一个元素的指针,而不是字符串文字本身。
 .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
        .....
        .....