我正在研究一个类的问题,我们正在学习C中的链表。我得到了一段代码来完成,特别是删除一个节点部分,我在删除头部时遇到了问题。每当我尝试删除头部时,我都会收到分段错误。有人能告诉我我做错了吗?
EDIT2 我的老师写了除查找和删除功能以外的所有内容。
我已经解决了莫斯科先生和Petriuc先生指出的明显错误,但是代码仍未运行。它确实可以编译,但是头部仍然存在问题。
以下是完整代码:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linkedList.h"
// keep an unsorted array of char *'s, strings.
/*
Create an empty node, return 0 if fail, 1 if succeed
*/
struct node * createNode() {
struct node *p = (struct node *) malloc(sizeof(struct node));
if (p == NULL) return 0;
p->prev = p->next = NULL;
p->data = NULL;
}
/*
Lookup string in the list, return pointer to node of first occurence, NULL if not found.
*/
struct node * lookup(struct node *head, char *s) {
struct node *p;
for(p=head; p!=NULL; p=p->next){
if(strcmp(s,p->data)==0){
return p;
}
// just like print, but check if strcmp(s, p->data) == 0, and if so then return p
}
return NULL;
}
/*
Insert new string into the linked list, return 1 if success, 0 if fail.
*/
int insert(struct node **head, char *newS, int insertDuplicate) {
struct node *p = lookup(*head, newS);
if (p == NULL || insertDuplicate) {
// create a new node, put it at the front.
p = createNode();
if (p == NULL) return 0;
// put the string in the new node
p->data = (char *) malloc(sizeof(char) * (1 + strlen(newS)));
if (p->data == NULL) return 0;
strcpy(p->data, newS);
// note: make changes and use old head before setting the new head...
p->next = *head; // next of new head is previous head
if (*head != NULL)
(*head)->prev = p; // previous of old head is new head
*head = p; // set the new head
}
return 1;
}
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *p,*pr,*ne;
// first do a lookup for string s, call lookup.
p=lookup(*head, s);
if(p==*head){
*head = p->next;
free(p);
return 1;
}
if(p!=NULL){
printf("%s",p);
pr = p->prev;
ne = p->next;
free(p->data);
free(p);
if(pr==NULL||ne==NULL){
return 0;
}
pr->next=ne;
ne->prev=pr;
// if lookup returns NULL, done, return 0.
// if lookup returns p, not NULL,
// pr = p->prev, ne = p->next
// set pr->next to ne, ne->prev to pr
// but what if pr or ne is NULL
// and note that we need node **head because if delete head,
// need to update head pointer back in calling function, in
// here if you want head probably do *head. like in insert.
// also, before the pointer to the one you're deleting is gone,
// free p->data and p.
return 1;
}
return 0;
}
void print(struct node *head) {
struct node *p;
for(p = head; p != NULL ; p = p->next) {
printf("%s\n", p->data);
}
}
答案 0 :(得分:2)
你在做什么
p-&gt; next = * head;
但p未分配到任何地方。
答案 1 :(得分:1)
你的功能没有意义。你可以调用函数lookup
三次。
此外,您使用未初始化的指针,例如
p->next = *head;
或
printf("%s",p);
pr = p->prev;
ne = p->next;
该功能可以按以下方式编写
int delete( struct node **head, char *s )
{
int success;
struct node *target = lookup( *head, s );
if ( ( success = target != NULL ) )
{
if ( target->prev != NULL )
{
target->prev->next = target->next;
}
else
{
*head = target->next;
}
if ( target->next != NULL )
{
target->next->prev = target->prev );
}
free( target );
}
return success;
}
考虑到函数的第二个参数和函数查找的相应参数应该用限定符const
声明
int delete( struct node **head, const char *s ) ;
^^^^^
struct node * lookup( struct node *head, const char *s );
^^^^^^
答案 2 :(得分:0)
简化删除()函数。我内联了lookup(),因为它的功能是没有价值的(你需要一个指向指针的指针,而不是一个指针来处理)
/*
Remove string from list if found, return 1 if found and deleted, 0 o/w.
*/
int delete(struct node **head, char *s) {
struct node *tmp;
// first do a lookup for string s, no need to call call lookup.
for( ;*head; head = &(*head)->next ){
if (!strcmp( (*head)->data, s)) break;
}
if (!*head) return 0; // not found
tmp = *head
*head = tmp->next
free(tmp);
return 1;
}