通过在堆与堆栈上分配创建的指针之间的差异

时间:2015-12-14 21:44:28

标签: c pointers

对于这种情况,我们有类似指针列表的指针。

// Allocating on Stack
typedef char *list[10];
char **pointer;
pointer = (list) {NULL};

// Allocating on Heap
char **pointer = calloc(10,sizeof(char *)); 
  

我对上面编写代码的方式是否正确?

     

另外,如果有人能解释两种情况下char **pointer的行为是否存在差异,是否有任何差异?

2 个答案:

答案 0 :(得分:2)

是的,代码有效C11。

  // Allocating on Stack
  typedef char *list[10];
  char **pointer1;
  pointer1 = (list) {NULL};

  // Allocating on Heap
  char **pointer2 = calloc(10,sizeof(char *));

pointer1[0], pointer1[1]... pointer1[9]:第一个元素初始化为NULL,其余元素初始化为零位模式 - 这可能是等效的。

pointer2[0Marc B], pointer2[1]... pointer2[9]内容设置为零。如果calloc()不是pointer2,那就是NULL所做的。

pointer1[0], pointer2[0], etc.都没有指向任何char

另请注意@Marc comment关于数据的使用寿命。 pointer1的数据仅在范围丢失(如函数返回)之前有效,而pointer2的数据在free()之前有效。

答案 1 :(得分:0)

根据复合文字的实例化位置,它可能具有静态或自动存储持续时间。假设以下代码(摆脱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退出时释放。具有自动存储持续时间的对象通常从堆栈中分配,但请记住&#34;堆栈&#34;是一个实现细节,不是由C语言定义的。

下一个变化:

#include <stdio.h>

int main( void )
{
  char **pointer = (char *[10]){NULL};
  ...  
}

它指向的pointerchar *的10元素数组都具有自动存储持续时间。两者都在main条目处留出存储空间,并且在main退出时都会释放存储空间。

如果您希望char *的10元素数组分配存储持续时间(即,在堆上存活),那么您将编写

char **pointer = malloc( sizeof *pointer * 10 );

喜欢&#34;堆栈&#34;,&#34;堆&#34;是一个实现细节,不是由C语言定义的。

通过malloc调用预留数组的存储空间,直到存在对free的相应调用。根据上述规则,pointer变量的存储仍然是静态的或自动的。创建具有分配存储持续时间的对象的唯一方法是使用malloccallocrealloc之一。