在为结构本身调用malloc之后,是否需要为该结构中的其他字段调用malloc()?

在为结构本身调用malloc之后,是否需要为该结构中的其他字段调用malloc()?,c,C,假设我有一个类型node\t typedef struct node{ char* value; struct node *next; }node_t; 当我想创建一个名为n1的新节点指针时,我调用malloc node_t *n1 = malloc(sizeof(node_t)); 现在我想访问并使用n1:value中的其他字段,接下来,我是否必须再次调用malloc来获取这些指针,如下所示: n1->value = malloc(sizeof(char)); n1-

假设我有一个类型node\t

typedef struct node{
    char* value;
    struct node *next;
}node_t;
当我想创建一个名为n1的新节点指针时,我调用malloc

node_t *n1 = malloc(sizeof(node_t));
现在我想访问并使用n1:value中的其他字段,接下来,我是否必须再次调用malloc来获取这些指针,如下所示:

n1->value = malloc(sizeof(char));
n1->next = malloc(sizeof(node_t));
或者在创建n1时第一次调用malloc()时,您是否已经完成了所有这些工作

我必须再次调用malloc来获取这些指针吗

这取决于您希望如何使用这些成员

当你malloc一个
节点时
你会得到内存来存储1)一个
字符
指针和2)一个
节点
指针。可以将这些指针设置为指向其他现有对象。但您也可以将这些指针设置为指向新的(动态分配的)对象

示例1

node_t *n1 = malloc(sizeof *n1);
assert(n1 != NULL);
n1->value = "Hello world";
n1->next = NULL;

node_t *n2 = malloc(sizeof *n2);
assert(n2 != NULL);
n2->value = "Have fun";
n2->next = NULL;

n1->next = n2;  // Create a linked list
在本例中,
节点的任何成员都没有直接的malloc。成员仅设置为指向其他对象

示例2

node_t *n1 = malloc(sizeof *n1);
assert(n1 != NULL);
n1->value = "Hello world";

n1->next = malloc(sizeof *n1->next);
assert(n1->next != NULL);
n1->next->value = "Have fun";
n1->next->next = NULL;
此示例的结果与第一个示例相同。它只是写了一点不同,即
n1
next
指针被指定指向一个新的malloc'ed
节点,而不是一个
n2
对象

示例3

char *str1= "Hello world";
char *str2= "Have fun";

node_t *n1 = malloc(sizeof *n1);
assert(n1 != NULL);
n1->value = malloc(1 + strlen(str1));
strcpy(n1->value, str1);  // Copy the string

n1->next = malloc(sizeof *n1->next);
assert(n1->next != NULL);
n1->next->value = malloc(1 + strlen(str2));
strcpy(n1->next->value, str2);  // Copy the string
n1->next->next = NULL;
在这里,
指针被设置为指向一个新的malloc'ed对象,并且字符串的副本被放置在该对象中


因此-重复-是否要为成员分配malloc内存取决于如何使用该结构。

malloc
分配一个新的
节点
,仅此而已。它不会初始化已分配的
结构的成员
,当然也不会为属于
结构的任何指针分配内存
sizeof(char)
始终为1[根据定义]。所以,不要使用它。因此,一般来说,您希望(例如)
charstr[]=“要存储的字符串”;n1->value=strdup(str)n1
时,您不会同时创建
下一个
节点。后面会出现这种情况[通常在随后调用create函数时]不要使用
assert
检查
malloc
的返回值<代码>断言
用于在调试期间检查编程错误,而不是运行时错误。c实现将
assert
定义为no-op完全可以。