全局声明是堆栈还是堆?

时间:2015-11-04 12:30:30

标签: c

我需要声明一个不在堆栈内存但在堆中的变量,如下面的

struct mystruct *name;

我应该在文件开头的所有函数之外(甚至在main()之外)声明它吗?

2 个答案:

答案 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存储持续时间的对象(使用allocatedmalloccalloc分配的任何内容)的生命周期从分配时间延长到明确显示通过调用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存储持续时间的对象;您可以通过allocatedmalloccalloc创建此类对象的唯一方法。无论您声明存储由任何这些函数返回的指针值的对象,都将具有reallocauto存储持续时间。

<小时/> 1。实际上,所有本地对象的存储都在函数入口处分配,并在函数出口处释放,无论对象的生命周期是在整个函数上还是仅限于函数内的块。但是,您永远不应该依赖于该对象生命周期之外可访问的存储。例如,statici的生命周期仅限于b循环;即使每个存储器的存储空间可能已在功能输入中分配,也不应尝试在循环体外部访问该存储器。

毕竟,C是在有堆叠的机器上设计的