为什么不需要释放静态数组?

bie*_*nle 31 c static scope return-value lifetime

我想知道为什么不需要释放静态数组?我知道在创建动态数组时,例如

int *p;
p = malloc(10*sizeof(int));
Run Code Online (Sandbox Code Playgroud)

我们必须使用以下内容释放分配的内存:

free(p);
Run Code Online (Sandbox Code Playgroud)

对于函数中的静态数组,静态数组将在被调用函数完成时自动释放.

我不明白的是:当使用如下函数返回静态数组时:

int *subFunc(){
    static int a[5] = {1,2,3,4,5};
    return a;
}

int main(){
    int *p;
    p = subFunc();
}
Run Code Online (Sandbox Code Playgroud)

如果在完成执行后自动释放静态数组,那么我们如何才能正确访问静态数组的值?

Sou*_*osh 43

如果在完成执行后自动释放静态数组,那么我们如何才能正确访问静态数组的值?

不,这不是那样的.static变量在开始之前被初始化main(),它的生命周期是程序的整个执行.因此,它们可以return从函数(定义它们)中编辑,但仍然可以访问.当函数完成执行时,它们不是本地的(对于函数).

相关的,引用自C11第6.2.4章

声明标识符的对象,如果没有存储类说明符 _Thread_local,并且具有外部或内部链接或使用存储类说明符static,则具有静态存储持续时间.它的生命周期是程序的整个执行,它的存储值只在程序启动之前初始化一次.

关于范围 a的static函数内部变量,是的,它被限制为函数本身,如第一章中提到§6.2.1,

[...]如果声明标识符的声明符或类型说明符出现在块内或函数定义中的参数声明列表中,则标识符具有块作用域,该作用域终止于关联块的末尾.[...]

这意味着,显然,您不能a在外面使用数组subFunc(),因为外部a可见subFunc().

但是,当你return的数组(返回一个数组导致衰减到指向数组的第一个元素的指针,FWIW)时,因为static数组的生命周期是程序的整个执行,访问返回的指针(当然,在边界内) )是完全有效和合法的.

  • `static` locals与`static` globals的行为略有不同:它们不是在程序启动时初始化,而是[当执行首次通过初始化点时](http://stackoverflow.com/questions/246564/what-is-的使用期限期的一静态可变在-AC-功能). (5认同)
  • @Quentin您确定C也是如此吗?你能链接一些参考吗? (4认同)
  • 显然我确实混淆了C和C++规则.我的错 ! (2认同)
  • @Quentin @Sourav尽管如此,你无法访问funtion-local`static`,直到你到达它的初始化点为止.在C中,`static`初始化器无论如何都可能没有副作用,所以你无法真正观察它何时被初始化. (2认同)

niy*_*asc 21

即使在定义它们的块终止之后,静态变量仍然存在.因此,在对同一函数的重复函数调用之间保留函数中的静态变量的值.静态自动变量的范围与自动变量的范围相同,即它是定义它的块的局部变量; 但是,分配的存储在程序期间变为永久存储.静态变量可以在其声明中初始化; 但是,初始化程序必须是常量表达式,并且在为静态变量分配内存时,在编译时只进行一次初始化.- 来源

当控件来自该函数时,不会释放静态数组或变量.静态变量的作用域是声明它的函数的本地,但它的生命周期是整个程序.

  • @Agostino当然,由于不是所有的静态变量都被一次性破坏,显然有些人喜欢_forever_的值比其他变量大.:-) (2认同)

lib*_*rik 10

对于子函数中的静态数组,当调用子函数完成时,静态数组将自动释放.

事实并非如此.输入函数时不会创建静态数组,并且在离开时不会销毁它们.

静态变量及其中的数据实际上很像全局变量!该函数的唯一本地是名称.(你会听到人们谈论变量的"范围" - 这意味着"我在哪里可以使用该名称来引用它.")

因此,当您考虑静态数组的生命时,您可以在心理上替换:

int *subFunc(){
    static int a[5] = {1,2,3,4,5};
    return a;
}
Run Code Online (Sandbox Code Playgroud)

int ONLY_USE_ME_INSIDE_SUBFUNC__a[5] = {1,2,3,4,5};  /* global variable */

int *subFunc(){
    int * a = ONLY_USE_ME_INSIDE_SUBFUNC__a;  /* a is the same as the global */
    return a;
}
Run Code Online (Sandbox Code Playgroud)

然后假装你的程序中没有其他人可以触及那个全局变量.