根据复合文字实例化的位置,它可能具有静态或自动存储持续时间。假设下面的代码(摆脱typedef
,使事情更清晰一点):
#include <stdio.h>
char **pointer = (char *[10]){NULL};
int main(void)
{
...
}
在这种特殊情况下,这两个变量pointer
和char
指针的10个元素的数组,它指向已申报/实例化在任何函数体外,所以它们都有静态存储时间;在程序启动时将存储设置保留,直到程序终止。 其中这个存储是从一个实现细节中分配的,但是对于ELF和PE对象以及二进制文件格式,这个空间被放置在堆栈或堆以外的内存段中。
如果我们改变,要
#include <stdio.h>
char **pointer = NULL;
int main(void)
{
pointer = (char *[10]){NULL};
...
}
可变pointer
具有静态存储持续时间,但char
指针10元件阵列,它指向具有自动存储持续时间;阵列的存储在main
的输入处被留出,并且当main
退出时被释放。具有自动存储持续时间的对象通常从堆栈中分配,但请记住,“堆栈”是一个实现细节,不是由C语言定义的。
下一页变化:
#include <stdio.h>
int main(void)
{
char **pointer = (char *[10]){NULL};
...
}
两者pointer
和char *
10元件阵列,它指向具有自动存储的持续时间。两者都在main
的条目处留出存储空间,并且两个都在main
退出时释放。
如果你想的char *
的10个元素的数组有分配存储时间(即住在堆),那么你会写
char **pointer = malloc(sizeof *pointer * 10);
像“堆栈”,“堆“是一个实现细节,并未由C语言定义。
该阵列的存储由malloc
呼叫留出并保持,直到出现free
的相应呼叫。根据上述规则,pointer
变量的存储仍为静态或自动。创建具有分配的存储持续时间的对象的唯一方法是使用malloc
,calloc
或realloc
之一。
calloc'd内存将在函数返回后停留,尽管它可能会“丢失”(例如内存泄漏)。当函数返回时,堆栈版本会自动消失。 –
'pointer'在这两种情况下的行为相同。 *指针指向*的东西可能会有所不同。 – immibis
怀疑一些倒票归因于对C11不熟悉,然后假设格式不正确的代码。 – chux