我可能遗漏了一些关于指针和内存管理的非常重要的东西。
我正在构建一个双向链表。我有一个struct Node
:
struct Node {
void* data;
nodep prev;
nodep next;
};
与nodep
作为指向此类 Node 的指针的 typedef:
typedef struct Node * nodep;
现在我写了一个insertAt()
函数,它需要 nodep lst
它基本上是指向列表中第一个元素的指针,或 NULL
对于空列表,int pos
,插入元素的位置和 v oid* data
,这是节点的有效负载。这是我的代码摘录,其中出现错误:
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;
}
这就是我打电话的方式insertAt()
在我的main()
功能:
int i;
nodep lst = NULL;
insertAt(lst, 0, "test");
当我使用 valgrind 运行程序时,我得到一个
Access not within mapped region at adress 0x10
对于这行代码:
lst = new;
我想做的是制作 nodep lst
指向nodep new
,这是列表的第一个元素。我真的不明白,为什么我会遇到这个错误。
预先感谢您的帮助。
干杯尼克
最佳答案
如果你想修改lst
,你必须使用双指针。
为了简单起见,我将使用 int
int i;
int* ptr = &i;
func(ptr);
func(int* p){
p = ....; //this won't change ptr!
}
func(&ptr);
func(int** p){
*p = ....; //this will change ptr!
}
如果是双指针且 sizeof(int) = 4
且 sizeof(int*) = 4
--------------- --------------- ---------------
|0x4|0x5|0x6|0x7| |0x0|0x1|0x2|0x3| | | | | |
--------------- --------------- ---------------
0x8 0x9 0xA 0xB 0x4 0x5 0x6 0x7 0x0 0x1 0x2 0x3
address of p address of ptr address of i
*p
将为您提供 i 的地址。这是 ptr
指向的地址。这就是为什么使用双指针可以更改“外部”指针。
关于c - 将指针分配给空指针时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48704909/