请参阅下面给出的这个程序。它在delete_node函数结束时崩溃。请告诉我出了什么问题。它在delete_node(5)调用结束时崩溃。调用delete_node后的printf语句未执行。
#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");
}
答案 0 :(得分:3)
以下是修正后的代码现在工作得非常好,顺便说一下这不是制作链表的好方法。
#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");
}
请仔细阅读我实施的链接列表,我相信这将更容易理解和编码
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
struct node{
char data;
struct node *next;
};
struct node *head=NULL;
void printMenu();
void getUserSelection(int *);
void performOperation(int );
void display(void);
void addNodeAtBeginning(void);
struct node* createNode(void);
void displayLinkedList(void);
void addNodeAtEnd(void);
void getDataFromUser(char*);
void addAtuserSpecificLocation(void);
int getLocationFromUser(void);
void deleteFirstNode(void);
void deleteLastNode(void);
void deleteFromAspecificPosition(void);
void deleteEntireList(void);
int main(){
int option=0;
while(9!=option){
printMenu();
getUserSelection(&option);
performOperation(option);
}
getchar();
return 0;
}
void printMenu(){
printf("\n");
printf("\n***********MENU***************\n");
printf("1) Add a node at the beginning\n");
printf("2) Add a node at the end\n");
printf("3) Add a node at a user selected position\n");
printf("4) Delete first Node\n");
printf("5) Delete last Node\n");
printf("6) Delete node at a user selected position\n");
printf("7) Display\n");
printf("8) Delete entire list\n");
printf("9) Exit");
}
void getUserSelection(int *number){
printf("\nSelect an option: ");
scanf("%d",number);
}
void performOperation(int option){
switch(option){
case 1:
addNodeAtBeginning();
break;
case 2:
addNodeAtEnd();
break;
case 3:
addAtuserSpecificLocation();
break;
case 4:
deleteFirstNode();
break;
case 5:
deleteLastNode();
break;
case 6:
deleteFromAspecificPosition();
break;
case 7:
displayLinkedList();
break;
case 8:
deleteEntireList();
break;
case 9:
exit(0);
break;
default:
printf("\n\n********Invalid option**************\n\n");
break;
}
}
void addNodeAtBeginning(void){
struct node *tempNode=NULL;
if(NULL==head) {
head= createNode();
}else{
tempNode=createNode();
tempNode->next=head;
head=tempNode;
}
}
void addNodeAtEnd(){
struct node*tempNode=NULL;
if(NULL==head) {
head=createNode();
}else{
tempNode=head;
while(NULL!=tempNode->next){
tempNode=tempNode->next;
}
tempNode->next=createNode();
}
}
struct node* createNode(){
struct node *tempNode;
tempNode= (struct node*)malloc(sizeof(struct node));
getDataFromUser(&tempNode->data);
tempNode->next=NULL;
return tempNode;
}
void displayLinkedList(){
struct node *tempNode;
printf("\n\n********************LINKED_LIST_DOUBLY*******************************\n\n\n");
tempNode=head;
printf("[head]-->");
while(NULL!=tempNode->next){
printf("[%c]", tempNode-> data);
printf("--->");
tempNode=tempNode->next;
}
printf("[%c]", tempNode->data);
printf("-->[X]");
printf("\n\n********************LINKED_LIST_DOUBLY*******************************\n\n\n");
}
void getDataFromUser(char * data){
fflush(stdin);
printf("Enter data: ");
scanf("%c",data);
}
void addAtuserSpecificLocation(void){
int location;
struct node *tempNode=NULL;
struct node *tempUserNode=NULL;
tempNode=head;
location=getLocationFromUser();
int i;
for(i=1;i<location-1;i++){
tempNode=tempNode->next;
}
tempUserNode=createNode();
tempUserNode->next=tempNode->next;
tempNode->next=tempUserNode;
}
int getLocationFromUser(void){
int location;
int linkedListLength;
linkedListLength=getLengthOfLinkedList();
while(location<0||location>linkedListLength){
printf("\n\nEnter a valid location: ");
scanf("%d",&location);
}
return location;
}
int getLengthOfLinkedList(){
struct node *temp;
int length=1;
if(NULL==head){
printf("\n\nLinked list is empty cannot perform operation\n\n");
}else{
temp=head;
while(temp->next!=NULL){
length++;
temp=temp->next;
}
}
return length;
}
void deleteFirstNode(void){
struct node *tempNode=NULL;
if(NULL!=head){
tempNode=head;
head=head->next;
free(tempNode);
}else{
printf("\n\nThere is no node to delete\n\n");
}
}
void deleteLastNode(void){
struct node *tempNode;
if(NULL!=head){
tempNode=head;
while(NULL!=tempNode->next){
tempNode=tempNode->next;
}
free(tempNode);
}else{
printf("\n\nThere is no node to delete\n\n");
}
}
void deleteFromAspecificPosition(void){
int location;
struct node *tempNode;
if(NULL!=head){
tempNode=head;
location = getLocationFromUser();
int listIterator=0;
for(listIterator=0; listIterator<location-1;listIterator++){
tempNode=tempNode->next;
}
free(tempNode);
}
}
void deleteEntireList(void){
struct node* tempNode;
struct node* tempNode2;
if(NULL==head){
printf("\n\nList is already empty\n\n");
}else{
tempNode=head;
while(tempNode->next!=NULL){
tempNode2=tempNode->next;
free(tempNode);
tempNode=tempNode->next;
}
free(tempNode2);
head=NULL;
printf("\n\nList Deleted\n\n");
}
}
答案 1 :(得分:1)
在delete_node(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);
答案 2 :(得分:1)
在delete_node
中,您声明变量prev
,但您没有为其指定任何值:
list* prev;
由于所需的值(5)位于第一个list元素中,它将执行以下语句:
prev->next = tmp->next;
prev
未定义,因此释放SegmentFault。
这就是造成错误的原因。
最简单的解决方案就是通过在声明中将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;
}
...
你也应该考虑在没有全局变量的情况下这样做。