2015-12-14 32 views
-3

对于这种情况,我们有类似指向指针列表的指针。通过分配堆或堆栈创建的指针之间的差异

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

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

上午我与我写上面的代码的方法正确吗?

此外,如果任何人都可以解释这两种情况下的行为char **pointer之间是否存在差异,如果有任何差异?

+1

calloc'd内存将在函数返回后停留,尽管它可能会“丢失”(例如内存泄漏)。当函数返回时,堆栈版本会自动消失。 –

+0

'pointer'在这两种情况下的行为相同。 *指针指向*的东西可能会有所不同。 – immibis

+0

怀疑一些倒票归因于对C11不熟悉,然后假设格式不正确的代码。 – chux

回答

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()

+0

前三行代码是否会在堆栈中分配一个数组,然后给我一个指向它的指针?或者它是否被分配到堆栈中?谢谢 – Charana

+0

堆栈和堆不是C规范的一部分。这取决于机器/编译器(这两者都未说明)。这第一个只声明一个类型(无代码)。第二行声明了一个指针。第3行将该指针指向复合文字“(list){NULL}”的地址,该地址很可能会分配到您的“堆栈”中。 – chux

+0

听起来正确。谢谢 – Charana

0

根据复合文字实例化的位置,它可能具有静态或自动存储持续时间。假设下面的代码(摆脱typedef,使事情更清晰一点):

#include <stdio.h> 

char **pointer = (char *[10]){NULL}; 

int main(void) 
{ 
    ... 
} 

在这种特殊情况下,这两个变量pointerchar指针的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}; 
    ... 
} 

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

如果你想的char *的10个元素的数组有分配存储时间(即住在堆),那么你会写

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

像“堆栈”,“堆“是一个实现细节,并未由C语言定义。

该阵列的存储由malloc呼叫留出并保持,直到出现free的相应呼叫。根据上述规则,pointer变量的存储仍为静态或自动。创建具有分配的存储持续时间的对象的唯一方法是使用malloc,callocrealloc之一。