C 获取并从链表中删除会导致分段错误

C 获取并从链表中删除会导致分段错误,c,segmentation-fault,C,Segmentation Fault,从链表中检索消息,然后从列表中删除该消息会导致分段错误 第一条消息和服务器消息结构: // used to store messages. struct server_message { char message[80]; char id[80]; struct server_message *next_msg; }; //head of the list static struct server_message *first_message = NULL; 获取消息

从链表中检索消息,然后从列表中删除该消息会导致分段错误

第一条消息和服务器消息结构:

// used to store messages.
struct server_message {
    char message[80];
    char id[80];
    struct server_message *next_msg;
};

//head of the list
static struct server_message *first_message = NULL;
获取消息函数

char *get_message(char *id) {
    char *message;
    char *not_found =(char *)  malloc( sizeof(char) * 20 );
    not_found = "No messages available";
    struct server_message *curr_msg = first_message;
    struct server_message *prev_msg = first_message;

    if (curr_msg != NULL && (strcmp(curr_msg->id, id) != 0)) {
        strcpy (message, curr_msg->message);
        //Remove message
        first_message = NULL;
        return message;
    }


    while (curr_msg->next_msg != NULL) {
        curr_msg = curr_msg->next_msg;

        if (strcmp(curr_msg->id, id) != 0) {
            strcpy (message, curr_msg->message);
            //Remove message
            prev_msg->next_msg = curr_msg->next_msg;
            return message;
        } else {
            prev_msg = curr_msg;
        }
    }
    return not_found;
}
更新的代码仍然存在seg错误

char *get_message(char *id) {
    char *message = (char *)  malloc( sizeof(char) * 80 );
    char *not_found=(char *)  malloc( sizeof(char) * 20 );
    strcpy(not_found, "No messages available");
    struct server_message *curr_msg = first_message;
    struct server_message *prev_msg = NULL;

    while (curr_msg->next_msg != NULL) {

        if (strcmp(curr_msg->id, id) != 0) {
            strcpy (message, curr_msg->message);
            //Remove message
            if (prev_msg == NULL) {
                first_message = curr_msg->next_msg;
            } else {
                prev_msg->next_msg = curr_msg->next_msg;
            }
            return message;
        } else {
            prev_msg = curr_msg;
            curr_msg = curr_msg->next_msg;
        }
    }
    return not_found;
}

修订完整示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// used to store messages.
struct server_message {
    char message[80];
    char id[80];
    struct server_message *next_msg;
};

//head of the list
static struct server_message *first_message = NULL;

char *get_message(char *id) {
    struct server_message *curr_msg = first_message;
    struct server_message *prev_msg = NULL;

    while (curr_msg != NULL) {               /* FIX1: iterate until we do not have an item */
        if (strcmp(curr_msg->id, id) == 0) { /* FIX2: 0 is equal */
            //Remove message
            if (prev_msg == NULL) {
                first_message = curr_msg->next_msg;
            } else {
                prev_msg->next_msg = curr_msg->next_msg;
            }
            return strdup(curr_msg->message);
        } else {
            prev_msg = curr_msg;
            curr_msg = curr_msg->next_msg;
        }
    }
    return strdup ("No messages available");
}

struct server_message d = {"foo-4", "4", 0};
struct server_message c = {"foo-3", "3", &d};
struct server_message b = {"foo-2", "2", &c};
struct server_message a = {"foo-1", "1", &b};

int main(int argc, char *argv[])
{
        char *t;

        first_message = &a;

        t = get_message("1");
        printf ("1: %s\n", t);
        free (t);

        t = get_message("3");
        printf ("3: %s\n", t);
        free (t);

        t = get_message("10");
        printf ("10: %s\n", t);
        free (t);

        return 0;
}
#包括
#包括
#包括
//用于存储消息。
结构服务器消息{
字符消息[80];
字符id[80];
结构服务器消息*下一个消息;
};
//榜首
静态结构服务器消息*第一条消息=NULL;
char*get_消息(char*id){
结构服务器消息*curr\u msg=第一条消息;
结构服务器消息*prev\u msg=NULL;
while(curr_msg!=NULL){/*FIX1:迭代直到没有项目为止*/
如果(strcmp(curr_msg->id,id)==0){/*FIX2:0等于*/
//删除消息
if(prev_msg==NULL){
第一条消息=当前消息->下一条消息;
}否则{
上一条消息->下一条消息=当前消息->下一条消息;
}
返回strdup(curr\u msg->message);
}否则{
prev_msg=curr_msg;
curr\u msg=curr\u msg->next\u msg;
}
}
返回strdup(“无可用消息”);
}
结构服务器_消息d={“foo-4”,“4”,0};
结构服务器_消息c={“foo-3”、“3”和&d};
结构服务器_消息b={“foo-2”、“2”和&c};
结构服务器_消息a={“foo-1”、“1”和&b};
int main(int argc,char*argv[])
{
char*t;
第一条消息=&a;
t=获取_消息(“1”);
printf(“1:%s\n”,t);
自由(t);
t=获取_消息(“3”);
printf(“3:%s\n”,t);
自由(t);
t=获取_消息(“10”);
printf(“10:%s\n”,t);
自由(t);
返回0;
}

Debugger………此代码严重损坏。内存泄漏、未初始化指针的取消引用等。只有两个问题:(1)
消息从未初始化,但您尝试将其存储。分段错误。(2) 
not\u found
设置为存储自
malloc
。但在使用该存储之前,
not\u found
会立即设置为常量字符串。内存泄漏。我相信还有更多。这似乎更像是不了解C而不是发现错误的问题。@tomkarze对于消息我可以使用
char message[80]
?只有在函数返回后不使用它。记住,这将在本地堆栈上。当函数返回时,它不可用。如果改为使用
malloc
,则必须对所有返回值使用它,并且调用者必须释放它。不要抛出malloc()的结果我试着像你提到的那样更新代码,但还是失败了。你介意看一看我发布的更新吗?你在
未找到的
中分配了20个字节,而
的“无可用消息”
超过了20个字节。另外,为指针
first\u message
添加一个空检查。我还没有发现20字节不够。。关于未找到的返回,最简单的方法是
返回strdup(“无可用消息”)但代码也存在内存泄漏。。