【问题标题】:String-based linked list in C produces segmentation faultC中基于字符串的链表产生分段错误
【发布时间】:2014-11-14 15:09:34
【问题描述】:
----------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct node {
    char *val;
    struct node *next;
};

void add_to_list(struct node **, char *);
void list_all_elements(struct node *);

int main (int argc, char **argv)
{

    char *val;
    struct node *head = NULL;

    do  {

        scanf("%s",val);
        add_to_list(&head, val);

    }
    while(val[0] != '\\');

    list_all_elements(head);
}

void add_to_list(struct node **head, char *val) 
{
    //This produces a segfault
    struct node *temp = malloc(sizeof *temp);

    //EDIT - Fixed as per comments
    temp->val = malloc(strlen(val) + 1);

    strcpy(temp->val, val);
    temp->next = NULL;

    if(head!=NULL)
        temp->next = *head;

    *head = temp;

}

void list_all_elements(struct node *head)   
{

    while(head!=NULL)   {

        printf("%s\n",head->val);
        head = head->next;
    }
}

这就是我为实现链表而编译的。现在,由于某种原因 malloc'ing 会产生分段错误。

可以肯定的是,我将 char * 替换为 char [] 并且代码运行良好。 malloc 是否因此而出错,或者是否有一些我似乎无法找到的微不足道的错误?

【问题讨论】:

  • head 不会为空,您应该检查 *head,但这不会改变任何东西,这意味着每次分配 temp->next = *head;这是正确的做法,你根本不需要 if (和 temp->next = NULL)
  • 1) char *val; --> char val[MAX_STRING_SIZE];

标签: c string pointers linked-list


【解决方案1】:

你没有在main中分配val

char *val;
...
scanf("%s",val);

但是这里val 没有分配,当你这样做的时候,scanf 会去 sigsegv

【讨论】:

  • 是的!就是这样。谢谢。
【解决方案2】:

您没有分配变量val 指向的内存以及您要读取字符串的位置。

char *val;

//... 

do  {

    scanf("%s",val);
    add_to_list(&head, val);

}

变量 val 未初始化,因此程序具有未定义的行为。

而函数add_to_list 无效。例如,sizeof(val) 始终具有与指向 char 的指针大小相同的值。它不会产生此指针指向的字符串的大小。而不是运算符sizeof,您应该使用函数strlen

函数可以写成这样

void add_to_list( struct node **head, const char *val ) 
{
    struct node *temp = malloc( sizeof *temp );

    size_t n = strlen( val );

    temp->val = malloc( n + 1 );
    strcpy( temp->val, val );

    temp->next = *head;

    *head = temp;
}

【讨论】:

  • 这个!谢谢!我太天真了!
  • 但是 scanf 不应该在那里抛出错误吗?
  • @user3576305 该程序具有未定义的行为,因此无法预测会发生什么。
  • @user3576305 也不要忘记释放所有分配的内存。
  • 是的。我只是在这里显示相关代码。
【解决方案3】:
temp->val = malloc(sizeof(val));

sizeof(val) 更改为strlen(val)+1

【讨论】:

  • strlen()+1 否则你将没有空间写\0
  • @user3576305:将sizeof *temp 更改为sizeof struct node。您正在取消引用一个未初始化的指针。
  • @Kevin 不,这是使用 sizeof 操作的合法方式。没有错。
猜你喜欢
  • 1970-01-01
  • 2020-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 2017-09-07
相关资源
最近更新 更多