c - 特定情况的分段错误(核心转储)
问题描述
我正在练习双向链表。在这个程序中,一切似乎都运行良好。在 Delete() 函数中,当我尝试删除第一个节点时,程序运行良好并删除了第一个代码。但是每当我给任何其他节点时,我总是会收到错误:分段错误(核心转储)。谁能告诉我我在这里做错了什么?
#include<stdio.h>
#include<stdlib.h>
struct Node{
struct Node *prev;
int data;
struct Node *next;
}*first = NULL;
void create(int A[], int n){
struct Node *t, *last;
int i;
first = (struct Node *)malloc(sizeof(struct Node));
first->data = A[0];
first->prev = first->next = NULL;
last = first;
for(i = 1; i < n; i++){
t = (struct Node *)malloc(sizeof(struct Node));
t->data = A[i];
t->prev = last->next;
t->next = NULL;
last->next = t;
last = t;
}
}
void Display(struct Node *p){
while( p != NULL){
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
int Length(struct Node *p){
int len = 0;
while(p){
len++;
p = p->next;
}
return len;
}
void insert(int index, int key){
struct Node *t, *p = first;
int i;
if(index < 0 || index > Length(p))
return;
t = (struct Node *)malloc(sizeof(struct Node));
t->data = key;
if(index == 0){
if(p == NULL){
t->prev = NULL;
t->next = NULL;
first = t;
}
else{
t->prev = NULL;
t->next = first;
first->prev = t;
first = t;
}
}
else{
for(i = 0; i < index - 1; i++) p = p->next;
t->next = p->next;
t->prev = p;
if(p->next) p->next->prev = t;
p->next = t;
}
}
int Delete(struct Node *p, int index){
int x = -1,i;
if(index < 1 || index > Length(p))
return -1;
if(index == 1){
first = first->next;
if(first)first->prev = NULL;
x = p->data;
free(p);
}
else{
for(i=0; i<index-1; i++)
p=p->next;
x=p->data;
p->prev->next=p->next;
if(p->next)
p->next->prev=p->prev;
free(p);
}
return x;
}
void main(){
int A[] = {2, 4, 6, 8, 10};
create(A, 5);
Display(first);
printf("%d is deleted\n",Delete(first, 3));
Display(first);
}
解决方案
你的索引有问题。
显然您希望第一个索引为 1 - 好的。
让我们调用索引为 2 的函数。
所以你会在这里结束:
else{
for(i=0; i<index-1; i++)
p=p->next;
x=p->data;
p->prev->next=p->next;
if(p->next)
p->next->prev=p->prev;
free(p);
}
这又是:
else{
for(i=0; i<2-1; i++) // notice
p=p->next;
x=p->data;
p->prev->next=p->next;
if(p->next)
p->next->prev=p->prev;
free(p);
}
或者
else{
for(i=0; i<1; i++) // notice
p=p->next;
x=p->data;
p->prev->next=p->next; // arghh... seg fault
if(p->next)
p->next->prev=p->prev;
free(p);
}
所以这与 head 元素和 seg 错误重叠,因为 head 没有 prev 元素。
建议:使用零索引
顺便说一句:从不
for(i=0; i<index-1; i++)
p=p->next;
要么将其更改为
for(i=0; i<index-1; i++) p=p->next;
或更好
for(i=0; i<index-1; i++)
{
p=p->next;
}
推荐阅读
- powershell - Connect-PnPOnline:术语“Connect-PnPOnline”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称
- algorithm - 恒定内存库采样,O(k) 可能吗?
- javascript - Vuex 竞争条件
- prolog - Prolog试图制作固定大小的空列表
- docker - 当我们想要在其上部署 dockerize 应用程序时,Amazon Elastic Container Service 与 Kubernetes 有何不同?
- heroku - 为什么在 pgadmin 4 上保存属性会出错
- tensorflow - Tensorflow 1.0:从恢复的 RNN 中检索隐藏状态
- sas - 计算中使用的提示或宏变量
- asp.net - 测试剃须刀页面应用程序
- java - 在Java 8中通过串口发送和接收数据的多平台方式?