对于这种情况,我们有类似指针列表的指针。
// Allocating on Stack
typedef char *list[10];
char **pointer;
pointer = (list) {NULL};
// Allocating on Heap
char **pointer = calloc(10,sizeof(char *));
我对上面编写代码的方式是否正确?
另外,如果有人能解释两种情况下
char **pointer
的行为是否存在差异,是否有任何差异?
答案 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};
...
}
它指向的pointer
和char *
的10元素数组都具有自动存储持续时间。两者都在main
条目处留出存储空间,并且在main
退出时都会释放存储空间。
如果您希望char *
的10元素数组分配存储持续时间(即,在堆上存活),那么您将编写
char **pointer = malloc( sizeof *pointer * 10 );
喜欢&#34;堆栈&#34;,&#34;堆&#34;是一个实现细节,不是由C语言定义的。
通过malloc
调用预留数组的存储空间,直到存在对free
的相应调用。根据上述规则,pointer
变量的存储仍然是静态的或自动的。创建具有分配存储持续时间的对象的唯一方法是使用malloc
,calloc
或realloc
之一。