【发布时间】:2018-07-20 04:04:04
【问题描述】:
我可能遗漏了一些关于指针和内存管理的非常重要的东西。
我正在建立一个双向链表。我有一个struct Node:
struct Node {
void* data;
nodep prev;
nodep next;
};
nodep 是指向此类节点的指针的 typedef:
typedef struct Node * nodep;
现在我写了一个insertAt() 函数,它接受一个nodep lst,它基本上是一个指向列表中第一个元素的指针,或者NULL 表示空列表,一个int pos,它的位置插入元素和avoid* data,这是Node的payload。这是我的代码的摘录,我收到错误:
nodep insertAt(nodep lst, int pos, void *data){
nodep new = malloc(sizeof(struct Node));
[...]
new -> data = data;
assert(new != NULL);
printf("memory allocated!\n");
/* insert at last position */
if(pos == -1) {
[...]
/* insert at first position */
} else if (pos == 0) {
if(lst == NULL) {
new -> next = lst;
lst = new;
} else {
[...]
}
/* insert at pos */
} else {
[...]
}
return new;
}
这就是我在main() 函数中调用insertAt() 的方式:
int i;
nodep lst = NULL;
insertAt(lst, 0, "test");
当我用 valgrind 运行我的程序时,我得到一个
访问不在地址 0x10 的映射区域内
对于这行代码:
lst = new;
我想要做的是让nodep lst 指向nodep new,这就是列表的第一个元素。我真的不明白,为什么我会遇到这个错误。
提前感谢您的帮助。
干杯尼克
【问题讨论】:
-
最好创建一个Minimal, Complete, and Verifiable Example 向我们展示。
-
使用
new作为变量名真的不是一个好习惯,在很多语言中都太像关键字了。 -
如果你 typedef 指针,它会使程序不可读。
-
另外,你知道C 按值 传递它的参数,这意味着它们被复制吗?这意味着在您的
insertAt函数中,变量lst是一个副本,并且修改该副本(例如分配给它)不会更改您传入的原始变量。您可能想要这样做关于在 C 中模拟通过引用传递的一些研究。 -
此外,
assert宏在典型的发布版本中被禁用。它作为一个健全性检查器的使用被大大夸大和过度使用,特别是因为它解决问题的方法是强制中止(崩溃)程序。或者在发布版本中什么都不做。
标签: c pointers segmentation-fault valgrind ansi-c