我不明白为什么需要使用指针然后使用动态内存来分配结构。有什么阻止我这样做吗:
typedef struct node {
char name[100];
int age;
struct node *next;
} node_t ;
int main(){
node_t *head = NULL;
node_t person2 = {"Alex", 15, NULL};
head = person2.name;
return 0;
}
而不是这个:
typedef struct node {
char name[100];
int age;
struct node *next;
} node_t ;
int main(){
node_t *head = NULL;
node_t *person1;
person1 = (node_t*)malloc(sizeof(node_t));
person1->next = NULL;
head = person1;
return 0;
}
我知道我们分配内存的地方是不同的,但是以“实用”的方式,这两种方式的工作方式不同吗?我问这个问题的原因是因为我在网上的每个示例中只看到了指向 malloc 方式的指针。 我可以同时使用这两种方式吗?
我将整个节点指向下一个节点:
head = person1;
下一个节点可以指向下一个节点的名称,例如:
person1->next = person2.name;
如果我没记错的话,当我们指向动态内存地址时,我们指向第一个数据类型的字节,在这种情况下将是 name[0] 字节。
malloc
分配的内存必须用
free
释放,而在堆栈上分配的内存不能用 free
amd 释放当包含的 frmae 退出时将自动释放。更糟糕的是,将此类指针传递给 free
或在框架退出后尝试使用它会导致未定义的行为,并且这两种情况可能一开始似乎有效,但后来会导致问题。一种可能是用单个位标志 onHeap
来标记每个节点,该标志是为分配了 malloc 的节点设置的,并为其他节点清除的。这样你至少知道给定的节点是否应该传递给
free
。这仍然无助于解决分配在堆栈上的节点的悬空指针在列表上时被释放的可能性。head = &person2;
而不是
head = person2.name;
当然你可以使用局部变量作为列表的节点。但在这种情况下,如果列表需要存储大量节点,那么您将需要声明不同的大量局部变量来表示效率低下的节点,并使您的程序非常庞大且不可读。