链接列表头没有跨越函数调用更新
我试图实现自己的链表,并且一直在学习关于动态内存分配和指针等的代码。当我尝试添加一些东西到我的链表时,我得到一个段错误,并且在使用调试器时,我意识到这是因为最初我的链表的头指针没有指向空,然后我的添加函数没有将头识别为空。但我有一个初始化函数,它将链表的头指针设置为NULL,但由于某种原因,一旦我退出初始化函数并加入add函数,头部不再指向NULL。链接列表头没有跨越函数调用更新
这里是我的代码:
list.h
typedef struct node{
int value;
struct node *next;
} Node;
typedef struct list{
Node *head;
} List;
list.c
void initialize(List *l){
if(l != NULL){
l = malloc(sizeof(List));
l->head = NULL;
}
}
void add(List *l, int a){
//Code
}
int main(){
List l;
initialize(&l)
add(&l, 2);
}
当我步入add函数,并打印出* L,我看到头部不指向0x0。我一直在挠头,为什么它不是。我认为这是与价值传递有关,但我不认为这是事实。我在这里做错了什么?
是的,传递值是你的罪魁祸首。您正在按值传递一个指针。
假设l
在您的main()
位于地址0xABCD
。然后你main()
被编译到
int main(void) {
List l;
initialize(0xABCD);
add(0xABCD, 2);
}
和你initialize()
调用如下(假设malloc()
成功,并在地址0xCDEF
分配内存:
void initialize(List *l) {
if(l != 0x0) {
l = 0xCDEF; // malloc()
l->head = 0x0;
}
}
这l = 0xCDEF
不会传播到main()
,因为l
传递按价值
你想要做的是
void initialize(List **l) {
if(l != NULL) {
*l = malloc(sizeof(List)); // note dereferencing the passed-by-value pointer
(*l)->head = NULL;
}
}
int main(void) {
List * l;
initialize(&l);
add(l, 2);
}
它将指针指向指向列表的指针(实际上是指向你的main()
中的指针的地址。它允许initialize()
中的代码更改main()
中的l
变量。
或者,你可以使用
List * list_init() {
List * retval = malloc(sizeof(List));
if(retval == NULL) { // you should check malloc return value
// abort(), print warning or just
return NULL;
}
retval->head = NULL;
return retval;
}
int main(void) {
List * l = list_init();
if(l == NULL) {
// handle the error
}
add(l, 2);
}
请注意,ADT初始化函数更常见有一个'List * initialize();'原型,做一个等价的'return l;'来返回'malloc''指针。 –
啊是的。我现在明白了。除了使用双指针之外,没有其他方法可以做到吗? –
我没有被初始化的原型收缩,但是让我们说我是这个函数,并且这个函数只用一个指针作为参数?我只是想了解复制,解除引用等。 –
你的代码编译了这一行l->malloc(sizeof(list));
看起来很奇怪。
创建只有一个参数的结构是不是真的有用,一个简单的typedef应该做的工作:生活在在堆栈上typedef Node* List
这并不奇怪。这就是你在链表中分配节点的方式。 –
这个问题已经被编辑过了'l-> malloc(sizeof(list));'不会编译,'l = malloc(sizeof(List));' –
您在主申报表()。你传递一个指向这个List的指针initailize()。然后你在堆上创建一个新的列表。当你从initialize()返回的时候,你仍然在使用栈中的列表。堆上的列表泄漏,您无法访问它。所以你永远不会初始化你传递的List作为add()的指针。你可以忘记初始化(),只需要有
l.head = NULL;
改为。
建议执行搜索stackoverflow.com的。这个问题已经回答了很多次。 – user3629249
由于这更多的是关于针对我的案例的指针的概念性问题,所以我不认为搜索问人家问题的人会帮助我。 –
无论您对指针使用有什么误解,发布代码的问题根源与许多关于stackoverflow上链接列表的问题都是一样的。 – user3629249