提问人:g1e2h3 提问时间:3/13/2023 最后编辑:Vlad from Moscowg1e2h3 更新时间:3/13/2023 访问量:55
我不完全理解 c 中的列表是如何工作的
I don't understand fully how lists in c work
问:
所以我试图在列表的开头添加一个元素。函数prepend_list位于第 27 行。我试图以两种不同的方式进行它,一种是返回一个列表,另一种是 void 函数。
#include "base.h"
#include "string.h"
typedef struct Node Node;
struct Node{
int value;
Node* next;
};
Node* new_node(int value, Node* next){
Node* new = xmalloc(sizeof(Node));
new->value = value;
new->next = next;
return new;
}
void free_list(Node* list){
Node* currentHead = list;
while(list != NULL){
currentHead = list;
list = list->next;
free(currentHead);
}
}
Node* prepend_list(int value, Node* list){
return new_node(value, list);
}
void test(void) {
Node* n = NULL;
n = new_node(1, new_node(3, NULL));
n = prepend_list(2, n);
for(Node* print = n;print != NULL;print = print->next){
printi(print->value);
if(print->next != NULL){
prints(", ");
}
}
printsln("");
free_list(n);
}
int main(void) {
test();
report_memory_leaks(true);
return 0;
}
但我不明白为什么我不能这样做
void prepend_list(int value, Node* list){
list = new_node(value, list);
}
当我尝试这样做时,测试函数中的列表 n 根本没有改变。相反,我得到了内存泄漏。有人能告诉我为什么吗?
答:
1赞
Vlad from Moscow
3/13/2023
#1
该函数处理作为参数传递给函数的表达式值的副本。
你可以想象这个功能
void prepend_list(int value, Node* list){
list = new_node(value, list);
}
和它的呼唤
Node* n = NULL;
prepend_list(2, n);
以下方式
prepend_list(2, n);
//...
void prepend_list(/* int value, Node* list */){
int value = 2;
Node* list = n;
list = new_node(value, list);
}
如您所见,函数的局部变量列表由传递的指针 n 的值初始化,并且在函数中更改的是局部变量列表。指针 n 保持不变。也就是说,函数按值接受其参数。
有两种方法可以解决问题和更改原始指针。
第一个是从函数返回一个新指针,并将其分配给原始指针,就像在程序中所做的那样。
n = prepend_list(2, n);
第二种是通过指向原始指针的指针间接地通过引用传递原始指针。并且取消引用指向原始指针的指针,该函数可以访问原始指针并可以更改它。例如
prepend_list(2, &n);
//...
void prepend_list(int value, Node ** list){
*list = new_node(value, *list);
}
评论
list = new_node(value, list);
list
Node *list
=>Node **list