C 链表分割错误
请参阅下面给出的程序。它在delete_节点函数结束时崩溃。请告诉我出了什么问题。它在delete_节点(5)调用结束时崩溃。调用delete_节点后的printf语句未执行C 链表分割错误,c,linked-list,C,Linked List,请参阅下面给出的程序。它在delete_节点函数结束时崩溃。请告诉我出了什么问题。它在delete_节点(5)调用结束时崩溃。调用delete_节点后的printf语句未执行 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stdbool.h> typedef struct _list{ int data; struct _list *next;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
typedef struct _list{
int data;
struct _list *next;
}list;
list* create_list(int val);
list* add_list(int val, bool ad_end);
int delete_node(int val);
void print_list(void);
list* head = NULL;
list* curr = NULL;
int main()
{
int val = 10;
list* mylist;
mylist = create_list(5);
add_list(val, true);
add_list(20, true);
add_list(30, true);
add_list(25, true);
print_list();
delete_node(5);
printf("\n I am here in main \n");
print_list();
return 0;
}
list* create_list(int val)
{
list* ptr =(list*) malloc(sizeof(list));
head = curr = ptr;
ptr->data = val;
ptr->next = NULL;
return ptr;
}
list* add_list(int val, bool add_end)
{
list* ptr =(list*) malloc(sizeof(list));
ptr->data = val;
ptr->next = NULL;
if(add_end) {
curr->next = ptr;
curr = ptr;
} else {
ptr->next = head;
head = ptr;
}
return ptr;
}
int delete_node(int val)
{
list* tmp = NULL;
list* prev;
tmp = head;
while(tmp){
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
prev->next = tmp->next;
if( tmp == head) {
head = tmp->next;
}
free(tmp);
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
break;
} else {
prev = tmp;
tmp = tmp->next;
}
printf("Node to be deleted not found \n");
}
return 1;
}
void print_list(void)
{
list* tmp = head;
while(tmp != NULL) {
printf("addr %p\t addr next %p\n", tmp, tmp->next);
printf(" Data is %d \n", tmp->data);
tmp = tmp->next;
}
printf("\n");
}
#包括
#包括
#包括
#包括
类型定义结构列表{
int数据;
结构列表*下一步;
}名单;
列表*创建_列表(int val);
列表*添加列表(int val,bool ad_end);
int delete_节点(int val);
作废打印清单(作废);
列表*head=NULL;
列表*curr=NULL;
int main()
{
int-val=10;
列表*我的列表;
mylist=创建列表(5);
添加_列表(val,true);
添加_列表(20,正确);
添加_列表(30,真);
添加_列表(25,真);
打印列表();
删除_节点(5);
printf(“\n我在main中\n”);
打印列表();
返回0;
}
列表*创建列表(int val)
{
list*ptr=(list*)malloc(sizeof(list));
水头=电流=ptr;
ptr->data=val;
ptr->next=NULL;
返回ptr;
}
列表*添加列表(int val,bool add_end)
{
list*ptr=(list*)malloc(sizeof(list));
ptr->data=val;
ptr->next=NULL;
如果(添加\结束){
当前->下一步=ptr;
curr=ptr;
}否则{
ptr->next=头部;
水头=ptr;
}
返回ptr;
}
int delete_节点(int val)
{
列表*tmp=NULL;
列表*prev;
tmp=头部;
while(tmp){
如果(tmp->data==val){
printf(“找到要删除的节点\n”);
上一步->下一步=tmp->下一步;
如果(tmp==水头){
head=tmp->next;
}
免费(tmp);
printf(“头部数据为%d\t头部%p\t添加nxt%p\n”,头部->数据,头部,头部->下一步);
打破
}否则{
prev=tmp;
tmp=tmp->next;
}
printf(“未找到要删除的节点”);
}
返回1;
}
作废打印列表(作废)
{
列表*tmp=头部;
while(tmp!=NULL){
printf(“addr%p\t addr next%p\n”,tmp,tmp->next);
printf(“数据是%d\n”,tmp->Data);
tmp=tmp->next;
}
printf(“\n”);
}
在删除节点(int val)
中,未初始化prev
指针。语句prev->next=tmp->next代码>提供未定义的行为。初始化指针:
list * prev = head;
printf语句也遵循free(tmp)代码>语句。printf在内存中打印已经取消分配的变量。免费调用应该在printf语句之后
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
free(tmp);
在delete_节点(int val)
中,未初始化prev
指针。语句prev->next=tmp->next代码>提供未定义的行为。初始化指针:
list * prev = head;
printf语句也遵循free(tmp)代码>语句。printf在内存中打印已经取消分配的变量。免费调用应该在printf语句之后
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
free(tmp);
在delete_node
中,声明变量prev
,但不为其赋值:
list* prev;
由于所需值(5)位于第一个列表元素中,它将执行以下语句:
prev->next = tmp->next;
由于prev
未定义,因此释放分段故障
这就是导致错误的原因
最简单的解决方案就是在声明中将prev
设置为NULL,并在while循环中检查它是否为NULL,从而处理所需元素是第一个元素的情况:
...
int delete_node(int val)
{
list* tmp = NULL;
list* prev = NULL;
tmp = head;
while(tmp){
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
if (prev) {
prev->next = tmp->next;
}
...
您也应该考虑不使用全局变量。 在代码> DeleTeEnguleNo.<代码>中,您声明变量<代码> PREV,但是您不给它赋值:
list* prev;
由于所需值(5)位于第一个列表元素中,它将执行以下语句:
prev->next = tmp->next;
由于prev
未定义,因此释放分段故障
这就是导致错误的原因
最简单的解决方案就是在声明中将prev
设置为NULL,并在while循环中检查它是否为NULL,从而处理所需元素是第一个元素的情况:
...
int delete_node(int val)
{
list* tmp = NULL;
list* prev = NULL;
tmp = head;
while(tmp){
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
if (prev) {
prev->next = tmp->next;
}
...
你也应该考虑不使用全局变量。
这里是你的代码经过修正,它现在工作得很好,顺便说一下,这不是制作链表的好方法。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
typedef struct _list{
int data;
struct _list *next;
}list;
list* create_list(int val);
list* add_list(int val, bool ad_end);
int delete_node(int val);
void print_list(void);
list* head = NULL;
list* curr = NULL;
int main()
{
int val = 10;
list* mylist;
mylist = create_list(5);
add_list(val, true);
add_list(20, true);
add_list(30, true);
add_list(25, true);
print_list();
delete_node(5);
printf("\n I am here in main \n");
print_list();
return 0;
}
list* create_list(int val)
{
list* ptr =(list*) malloc(sizeof(list));
head = curr = ptr;
ptr->data = val;
ptr->next = NULL;
return ptr;
}
list* add_list(int val, bool add_end)
{
list* ptr =(list*) malloc(sizeof(list));
ptr->data = val;
ptr->next = NULL;
if(add_end&&head!=NULL) {
while(curr->next!=NULL){
curr= curr->next;
}
curr->next=ptr;
curr = ptr;
} else {
ptr->next = head;
head = ptr;
}
return ptr;
}
int delete_node(int val)
{
list* tmp = NULL;
list* prev;
tmp = head;
while(tmp->next!=NULL){
prev=tmp;
if( tmp == head&&head->next!=NULL) {
head = tmp->next;
free(tmp);
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
break;
}
if( tmp->data == val) {
printf(" Found the node to be deleted\n");
tmp=tmp->next;
prev->next=tmp->next;
free(tmp);
printf(" Head data is %d \t head %p\t add-nxt %p\n", head->data, head, head->next);
break;
} else{
printf("Node to be deleted not found \n");
}
}
return 1;
}
void print_list(void)
{
list* tmp = head;
while(tmp != NULL) {
printf("addr %p\t addr next %p\n", tmp, tmp->next);
printf(" Data is %d \n", tmp->data);
tmp = tmp->next;
}
printf("\n");
}
#包括
#包括
#包括
#包括
类型定义结构列表{
int数据;
结构列表*下一步;
}名单;
列表*创建_列表(int val);
列表*添加列表(int val,bool ad_end);
int delete_节点(int val);
作废打印清单(作废);
列表*head=NULL;
列表*curr=NULL;
int main()
{
int-val=10;
列表*我的列表;
mylist=创建列表(5);
添加_列表(val,true);
添加_列表(20,正确);
添加_列表(30,真);
添加_列表(25,真);
打印列表();
删除_节点(5);
printf(“\n我在main中\n”);
打印列表();
返回0;
}
列表*创建列表(int val)
{
list*ptr=(list*)malloc(sizeof(list));
水头=电流=ptr;
ptr->data=val;
ptr->next=NULL;
返回ptr;
}
列表*添加列表(int val,bool add_end)
{
list*ptr=(list*)malloc(sizeof(list));
ptr->data=val;
ptr->next=NULL;
if(添加头和尾!=NULL){
while(当前->下一步!=NULL){
当前=当前->下一步;
}
当前->下一步=ptr;
curr=ptr;
}否则{
ptr->next=头部;
水头=ptr;
}
返回ptr;
}
int delete_节点(int val)
{
列表*tmp=NULL;
列表*prev;
tmp=头部;
while(tmp->next!=NULL){
prev=tmp;
如果(tmp==head&&head->next!=NULL){
head=tmp->next;
免费(tmp);
printf(“头部数据为%d\t头部%p\t添加nxt%p\n”,头部->数据,头部,头部->下一步);
打破
}
如果(tmp->data==val){
printf(“找到要删除的节点\n”);
tmp=tmp->next;
上一步->下一步=tmp->下一步;
免费(tmp);
printf(“头部数据为%d\t头部%p\t添加nxt%p\n”,头部->数据,头部,头部->下一步);
打破
}否则{
printf(“未找到要删除的节点”);
}