目的:创建一个单独的链表,并使用HEAD POINTER(而不是HEAD NODE)打印列表。
**start
:
-
是HEAD NODE (FIRST NODE)指针
-
不是将HEAD NODE(FIRST NODE)存储为
*start
,而是将HEAD NODE指针存储为**start
。
ALG:
- 创建五个节点的列表(在我的程序中硬编码)。
- 使用指向HEAD NODE的指针显示它们
代码中有一个重要的漏洞,不容易出现。谁能给你的意见吗?
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *link;
}**start;
void display(void) {
struct node *p;
if (!strart ) { printf("List is emptyn"); return; }
p = *start;
printf("List :");
while(p != NULL) {
printf("-%d", p->data);
p = p->link;
}
puts("");
}
struct node **createlist(void) {
int n;
struct node *p, *new, *tmp;
printf("enter no of elements to addn");
//scanf("%d", &n);
p = NULL;
n=5;
while(n--) {
new = (struct node *) calloc(1, sizeof(struct node));
new->data = n;
if (p) {
p->link = new;
p = new;
} else if (p == NULL) {
p = tmp = new;
}
}
printf("before assign start :%pn", start);
start = &tmp;
printf("after assign start :%pn", start);
printf("In create List :n");
display();
return start;
}
int main() {
int ch;
do {
printf("1.CreateList 2.DisplayListn");
//scanf("%d", &ch); //HARDCODED
switch(1) {
printf("switch -> start :%pn", start);
case 1 : start = createlist();
printf("after create -> start :%pn", start);
case 2 : printf("Disp:n"); display(); break;
default : printf("Invalid optionn");
}
} while(0);
return 0;
}
代码输出:
root@CDrive:~/datastructures# ./a.out
1.CreateList 2.DisplayList
enter no of elements to add
before assign start :(nil)
after assign start :0x7ffd13e64798
In create List :
List :-4-3-2-1-0
after create -> start :0x7ffd13e64798
Disp:
Segmentation fault (core dumped)
在这里,您为start
分配了一个临时的、函数局部对象的地址:
start = &tmp;
之后返回那个地址:
return start;
从这里返回的指针指向一个不再存在的对象。
我不清楚你为什么把start
声明为struct node **
。你说:
**start:是HEAD NODE (FIRST NODE)指针
…但事实并非如此。**start
是一个节点,而不是指针。可以使*start
指向第一个节点。start
被声明为指向节点指针的指针。
不是将HEAD NODE(FIRST NODE)存储为*start,而是将HEAD NODE指针存储为**start
你不能;正如声明的那样,它不是正确的类型。**start
是一个节点,你不能在其中存储节点指针。*start
是指向节点的指针,start
是指向节点的指针。
我真的认为start
应该被声明为struct node *
而不是struct node **
。你似乎误解了双星的意思。
问题出现在这里随着函数createist()的返回,它的堆栈帧被销毁,甚至变量temp也被销毁。因此,temp变量不再存在,并且列表的第一个节点的地址在temp中,因此值*start在main函数中变为零,并且访问元素总是会出现分段错误。
start = &tmp;
printf("after assign start :%pn", start);
printf("In create List :n");
display();
为了克服这个问题,可以使用全局头指针来保存第一个节点的地址,或者您可以将tmp变量作为全局变量。