【问题标题】:Malloc crash when trying to load a linked list尝试加载链表时 Malloc 崩溃
【发布时间】:2018-07-31 00:01:08
【问题描述】:

我正在尝试从文本文件初始化一个链表,这是我的结构:

typedef struct Diagnostic
{
    char* disease;
    int priority;
}Diagnostic;

typedef struct Fiche Fiche;
struct Fiche
{
    char* name;
    int age;
    Diagnostic diagnostic;

    Fiche* next; // because this is a linked list
};

这是我的加载函数:

void loadFiches()
{
    int i;
    char tmp1[100], tmp2[100];
    Fiche* current;
    FILE* file = fopen("fiches.txt", "r");

    if(file != NULL)
    {
        while(!feof(file))
        {
            printf("malloc:");
            current = malloc(sizeof(Fiche)); // allocate memory for a new fiche
            printf("%p\n", current);

            fgets(tmp1, 100, file); // get the name
            cleanChar(tmp1); // remove '\n'

            fscanf(file, "%d\n", &current->age); // get the age

            fgets(tmp2, 100, file); // get the disease
            cleanChar(tmp2); // remove '\n'

            fscanf(file, "%d\n", &current->diagnostic.priority); // get the priority

            current->diagnostic.disease = malloc(strlen(tmp2) * sizeof(char)); // allocate memory for the disease
            strcpy(current->diagnostic.disease, tmp2); // copy the disease in the corresponding field

           // Then I add this fiche to my linked list
        }

    }
    else printf("error");

    fclose(file);
}

这个的输出是

malloc:00350FD8
malloc:00350FF8
malloc:

所以它在第三个 malloc 处崩溃。请注意,我只初始化疾病字段,因为这是导致崩溃的原因,其他一切正常,因此它不会出现在此代码中。 另请注意,在调试模式下一切正常。

如果我删除 cleanChar(tmp2);strcpy(current->diagnostic.disease, tmp2);,它也可以正常工作(但在第一种情况下我有一个不需要的 \n),这是导致崩溃的两条线的组合。

这是我的 cleanChar 函数:

void cleanChar(char string[100])
{
    int i;

    for(i = 0; i < strlen(string); i++)
        if(string[i] == '\n') string[i] = '\0';
}

有没有人知道什么可能导致崩溃?我很确定这与我将 fiches 保存到文本文件的方式无关,但这里是保存功能:

void saveFiches(List list)
{
    int i;
    Fiche* current = list.first;
    FILE* file;

        file = fopen("fiches.txt", "w+");

        if(file != NULL)
        {
            for(i = 0; i < list.size; i++)
            {
                fprintf(file, "%s\n%d\n%s\n%d\n", current->name, current->age, current->diagnostic.disease, current->diagnostic.priority);
                current = current->next;
            }
        }
        else printf("error");

        fclose(file);
}

List 是一个包含我的链表的第一个元素的结构。

【问题讨论】:

  • malloc(strlen(tmp2) * sizeof(char)) -> malloc(strlen(tmp2) + 1)(你需要空间来终止'\0')。
  • 请注意,您的标题具有误导性,您可能认为这是malloc() 的错,但事实并非如此。问题出在其他地方,也许是上面的评论指出的地方,但不是malloc()
  • 你的输入文件是什么样的?
  • @Drakalex 请注意,sizeof(char) 必须为 1,并且它是由 c 标准规定的。
  • 使用strdup() 来帮助避免将来出现此类问题(并使代码更易于阅读)。

标签: c string linked-list malloc fgets


【解决方案1】:

你的字符串malloc() 减一(你不考虑终止'\0'

current->diagnostic.disease = malloc(strlen(tmp2) * sizeof(char));

应该是:

current->diagnostic.disease = malloc((strlen(tmp2) + 1) * sizeof(char));

而且,由于 sizeof(char) 始终是 1,这可能是:

current->diagnostic.disease = malloc(strlen(tmp2) + 1);

除非您想通过取消引用分配给它的指针来使malloc() 更健壮,以确定适当的大小:

current->diagnostic.disease = malloc((strlen(tmp2) + 1) *
  sizeof(*(current->diagnostic.disease)));

你也可以复制字符串:

current->diagnostic.disease = strdup(tmp2);

无论您采用哪种方式,都不要忘记检查NULL的结果

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-10
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 2015-12-11
    相关资源
    最近更新 更多