我需要声明一个不在堆栈内存但在堆中的变量,如下面的
struct mystruct *name;
我应该在文件开头的所有函数之外(甚至在main()之外)声明它吗?
答案 0 :(得分:1)
请注意,变量从不在堆上声明“。只有指针指向的内存可以在堆上分配。
在您的示例中,您可以在任何函数之外声明name
,然后它将存在于全局内存中。您还可以在函数内部对变量进行delcare,前面是关键字static
。后者也将在全局内存中分配变量,但它只在您声明它的函数中可见。
要使用指针变量,您现在必须为它指定内存,使用malloc
在堆上分配它。
答案 1 :(得分:0)
TL; DR版本
您无法声明变量,使变量本身存在于堆上。
James Michener版本
C语言定义不讨论堆栈或堆;它谈到存储持续时间。
具有auto
存储持续时间的对象(在块内声明且没有static
关键字的任何内容)的生命周期从该块的开头延伸,并在块退出 1时结束:
void foo( void )
{
int a = 0; // lifetime of a extends to the end of
// the function
for ( int i = 0; i < 10; i++ ) // lifetime of i and b extend to the end
{ // of the for loop
int b = a + i;
printf( "b = %d\n", b );
}
}
大多数实现为硬件堆栈中的auto
对象分配存储空间,因为堆栈使得该行为易于实现 2 。
具有static
存储持续时间的对象(在函数外部或使用static
关键字声明的任何内容)的生命周期从程序加载到内存到程序退出时延长:
int a = 0; // lifetime of a extends over the lifetime of
// the entire program
int main( void )
{
static int b = 10; // lifetime of b also extends over the lifetime
// of the program, but is only visible within
// main
...
}
大多数实现都会为可执行文件本身内的static
个对象预留存储空间(对于使用ELF格式的可执行文件,这些对象将存储在.bss
,{ {1}}或图片的.data
部分)。
具有.rodata
存储持续时间的对象(使用allocated
,malloc
或calloc
分配的任何内容)的生命周期从分配时间延长到明确显示通过调用realloc
取消分配。
free
变量 int *foo( size_t size )
{
int *ptr = malloc( sizeof *ptr * size );
return ptr;
}
void bar( void )
{
int *p = foo( 10 );
// do something with p
free( p );
}
和ptr
仅在其各自功能的生命周期内存在,并且通常从堆栈中分配。变量指向的对象在从p
分配之前一直存在,直到用malloc
取消分配。
大多数实现为堆中的free
个对象分配存储空间。
您无法声明具有allocated
存储持续时间的对象;您可以通过allocated
,malloc
或calloc
创建此类对象的唯一方法。无论您声明存储由任何这些函数返回的指针值的对象,都将具有realloc
或auto
存储持续时间。
<小时/> 1。实际上,所有本地对象的存储都在函数入口处分配,并在函数出口处释放,无论对象的生命周期是在整个函数上还是仅限于函数内的块。但是,您永远不应该依赖于该对象生命周期之外可访问的存储。例如,
static
和i
的生命周期仅限于b
循环;即使每个存储器的存储空间可能已在功能输入中分配,也不应尝试在循环体外部访问该存储器。