【问题标题】:How to properly add a char* to a linked list without seg fault如何在没有段错误的情况下正确地将 char* 添加到链表
【发布时间】:2026-01-31 20:05:01
【问题描述】:

我正在尝试将值(文件路径的字符数组)添加到链接列表。我不断从我的 _add 函数中得到一个 Seg 错误,我不知道如何修复它。我尝试了许多不同的方法来编写函数,但我一无所获。答案似乎很简单,我就是不明白。这是我的 _add 函数代码:

    typedef struct cplist {
        char *path; 
        int cpid;
        time_t  tv_sec;   
        suseconds_t tv_usec;
        struct cplist *next;
    } cplist;

cplist *cpl_add(cplist *head, char *path){
    cplist *current = head;
    while(current->next != NULL){
        current = current->next;
    }

    current->next = (cplist*) malloc(sizeof(cplist));
    current->next->path = path;
    current->next->next = NULL;
}

这是我在主程序中的代码。我正在读取一个可选的“-v”标志,然后是一个整数,然后是必须添加到链表的路径:

int main(int argc, char* argv[]){
    int i, j;
    char *p;
    char *key;
    cplist *head = NULL;
    for(i = 0; i < argc; i++){
        if(strcmp(argv[1], "-v") == 0){
            key = argv[2];
            for(j = 3; j < argc; j++){
                p = argv[j];
                cpl_add(head, p);
            }
        } else {
            key = argv[1];
            for(j = 2; j < argc; j++){
                p = argv[j];
                cpl_add(head, p);
            }
        }
    }

【问题讨论】:

  • 注意:sizeof(head)头指针的大小,而不是结构的大小。你应该使用sizeof(cplist)
  • 你是对的。我会确保编辑它

标签: c linked-list segmentation-fault


【解决方案1】:

当您拨打cpl_add(head, p) 时,您实际上是在拨打cpl_head(NULL, p)

然后你打电话给NULL-&gt;next,它会爆炸。

  • 在添加到树之前使用 malloc 初始化 head
  • 务必确保将此元素中的链表指针设置为NULL

你可以做的其他事情:

  • 去掉无用的p变量,直接用cpl_add(head, argv[j])调用,避免歧义。

【讨论】:

  • 谢谢你,一旦我用 malloc 而不是 NULL 初始化了头部,修复了 seg 错误
  • 如果遇到这种情况,别忘了在调试器中单步调试代码。如果您密切关注变量的状态,通常可以发现这样的问题。
  • @JoshPokorny 用 malloc 初始化头节点是个很糟糕的主意。所有节点都应由该函数创建。看我的回答。
【解决方案2】:

该函数通常是不正确的,因为当最初传递的指向 head 的指针等于 NULL 时,它不处理列表。

你应该复制传递的字符串。

此外,该函数的返回类型与void 不同,但不返回任何内容。

除此之外,该语句中还有一个错误

current->next = (cplist*) malloc(sizeof(head));

您没有为节点分配内存。您正在为指针分配内存。不一样。

函数可以如下所示。

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

//...

int cpl_add( cplist **head, const char *path )
{
    cplist *current = malloc( sizeof( cplist ) );

    int success =  current != NULL;

    success = success && ( current->path = malloc( strlen( path ) + 1 ) );

    if ( !success )
    {
        free( current );
    }
    else
    {
        strcpy( current->path, path );
        current->next = NULL;

        while ( *head != NULL ) head = &( *head )->next;

        *head = current;
    }

    return success;
}

并调用函数,例如

cpl_add( &head, argv[j] );

【讨论】:

    最近更新 更多