为什么我不能将指针分配给双指针的指针?我每次都遇到分段错误。
#include <stdio.h>
int main() {
int **pointer1, *pointer2, *pointer3, var;
var = 10;
pointer3 = &var;
pointer1 = &pointer3;
pointer2 = *pointer1; //correcting my mistake, so this is now correct?
return 0;
}
我实际正在处理的代码,练习链表:
#include <stdio.h>
#include <stdlib.h>
typedef struct node_t {
int num;
struct node_t *next;
} node_t;
void insert(int, node_t**);
int main(void) {
int list;
node_t **head, *temp;
*head = NULL;
while (scanf("%d", &list) != EOF) {
insert(list, head);
}
temp = *head;
/*while (temp != NULL) { //here is the problem, if I remove this
//I get segmentation fault but it runs
printf("%d ", temp->num); //runs fine when I include it
temp = temp->next;
}*/
return 0;
}
void insert(int list, node_t **head) {
node_t *temp = malloc(sizeof(node_t));
temp->next = (*head);
temp->num = list;
(*head) = temp;
}
就像我在代码注释中输入的内容一样,当我在没有 while 循环的情况下编译它时,上述版本的代码会出现分段错误。但奇怪的是,一旦我包含 while 循环,它就可以正常工作。在摆弄之后,我怀疑罪魁祸首是双指针,我试图将辅助地址分配给常规指针。 但是这个版本实际上运行良好:
#include <stdio.h>
#include <stdlib.h>
typedef struct node_t {
int num;
struct node_t *next;
} node_t;
void insert(int, node_t**);
int main(void) {
int list;
node_t *head, *temp;
head = NULL;
while (scanf("%d", &list) != EOF) {
insert(list, &head);
}
temp = head;
while (temp != NULL) {
printf("%d ", temp->num);
temp = temp->next;
}
return 0;
}
void insert(int list, node_t **head) {
node_t *temp = malloc(sizeof(node_t));
temp->next = (*head);
temp->num = list;
(*head) = temp;
}
在这里,我将地址传递到链表函数中,本质上我正在做同样的事情,但没有双指针。
附带说明一下,我已经看到了链表的许多不同的实现。我的需要双指针,因为我使用的是void insert(int, **node_t)
,但是有些版本返回地址并更新头部:node_t* insert(int, *node_t)
和全局链表:void insert(int)
。只是想知道哪些版本实际上是推荐的,更容易调试并且对初学者友好。
您的第一个示例段错误,因为*pointer1
(以及之前的pointer1
(没有指向任何内容。它是一个未初始化的指针,指向内存中的随机垃圾数据。
试图取消引用这样的指针(**pointer1 = 10;
(会导致segfault
。
使您的第一个示例工作的解决方案是为尝试存储的数据分配一些内存:
int **pointer1, *pointer2;
int *data = malloc(sizeof(int));
pointer1 = &data;
**pointer1 = 10;
pointer2 = *pointer1;
free(*pointer1); //or free(data)
当你这样做时:
**pointer1 = 10;
这说的是"获取存储在pointer1
中的地址,取消引用该地址,获取存储在那里的地址,再次取消引用,并将值 10 存储在该位置"。
它看起来像这样:
pointer1
------- ------- ------
| .--|---->| .--|--->| 10 |
------- ------- ------
你得到一个段错误,因为pointer1
目前没有指向任何地方。
如果您执行以下操作,这可能会起作用:
int **pointer1, *pointer2, value;
value = 10;
pointer2 = &value;
pointer1 = &pointer2;
在两个"真实"代码片段的情况下,第一段代码的问题在于你head
未初始化传递给insert
,然后取消引用head
。 这与上述问题相同。 同样的事情在main
中再次发生,因为调用head
后仍未初始化list
因为它是按值传递的。 第二段代码之所以有效,是因为您将head
的地址传递给insert
,因此随后取消引用它是有效的。