【问题标题】:munmap_chunk(): invalid pointer while freeing a struct in an arraymunmap_chunk():释放数组中的结构时指针无效
【发布时间】:2020-11-16 09:55:44
【问题描述】:

所以我编写了一个程序,每当我想向其中添加一些东西时,我都必须重新分配结构数组。 但是当我尝试释放数组时,我会单独释放每个元素,但有时会得到munmap_chunk(): invalid pointer

这里是完整的代码:

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

struct Date {
    int day;
    int month;
    int year;
};

struct Person {
    char *name;
    char *surname;
    struct Date birth;
};

struct Directory {
    int size;
    struct Person *array;
};

struct Date create_date() {
    struct Date date = {
            .day = 0,
            .month = 0,
            .year = 0
    };

    return date;
}

struct Directory create_directory() {
    struct Directory directory = {
            .size = 0,
            .array = NULL
    };

    return directory;
}

struct Person *create_person() {
    struct Person *person_ptr = (struct Person *) malloc(sizeof(struct Person));

    person_ptr->name = NULL;
    person_ptr->surname = NULL;

    return person_ptr;
}

void copy_date(struct Date *dest, struct Date *src) {
    dest->day = src->day;
    dest->month = src->month;
    dest->year = src->year;
}

void initialize_person(struct Person *person_ptr, char *name, char *surname, struct Date *birth) {
    if (name != NULL && surname != NULL && birth != NULL) {
        person_ptr->name = realloc((*person_ptr).name, (strlen(name) * sizeof(char)) + 1);
        strcpy(person_ptr->name, name);

        person_ptr->surname = realloc((*person_ptr).surname, (strlen(surname) * sizeof(char)) + 1);
        strcpy(person_ptr->surname, surname);

        copy_date(&person_ptr->birth, birth);
    }
}

void copy_person(struct Person *dest, struct Person *src) {
    dest->name = realloc((*dest).name, (strlen(src->name) * sizeof(char)) + 1);
    dest->surname = realloc((*dest).surname, (strlen(src->surname) * sizeof(char)) + 1);

    struct Date date = create_date();
    dest->birth = date;

    strcpy(dest->name, src->name);
    strcpy(dest->surname, src->surname);
    copy_date(&dest->birth, &src->birth);
}

int add_person(struct Directory *directory_ptr, const struct Person *new_person_ptr) {
    int return_code = 0;

    directory_ptr->size++;
    directory_ptr->array = realloc(directory_ptr->array, (directory_ptr->size * sizeof(struct Person)));

    if (directory_ptr->array) {
        copy_person(&directory_ptr->array[directory_ptr->size - 1], (struct Person *) new_person_ptr);
    } else {
        return_code = 1;
    }

    return return_code;
}

int add_multiple_persons(struct Directory *directory_ptr, const struct Person **persons_ptr, int nb_persons) {
    for (int i = 0; i < nb_persons; i++) {
        add_person(directory_ptr, (persons_ptr[i]));
    }

    return 0;
}

void destroy_person(struct Person *person_ptr) {
    free(person_ptr->name);
    person_ptr->name = NULL;

    free(person_ptr->surname);
    person_ptr->surname = NULL;

    free(person_ptr);
    person_ptr = NULL;
}

void destroy_directory(struct Directory *directory_ptr) {
    if (directory_ptr->array) {
        for (int i = 0; i < directory_ptr->size; i++) {
            destroy_person(&directory_ptr->array[i]);
        }
        directory_ptr->array = NULL;
        directory_ptr->size = 0;
    }
}

int main(void) {
    struct Directory directory = create_directory();
    struct Person *person1 = create_person();
    struct Person *person2 = create_person();
    struct Person *person3 = create_person();
    struct Date date = {
            .day = 17,
            .month = 04,
            .year = 1999};

    initialize_person(person1, "Marcel", "Juan", &date);
    initialize_person(person2, "Albin", "Michel", &date);
    initialize_person(person3, "Suzerain", "Bernard", &date);

    const struct Person *array[] = {
            person1,
            person2,
            person3
    };

    add_multiple_persons(&directory, array, 3);
    destroy_person(person1);
    destroy_person(person2);
    destroy_person(person3);
    destroy_directory(&directory);

    return 0;
}

这个错误我已经有一个多星期了,它一直困扰着我。 我该如何解决这个问题?

【问题讨论】:

  • 能否请您澄清错误出现在哪一行执行之后?
  • 错误发生在第 109 行,在从 destroy_directory() 调用 destroy_person() 之后

标签: arrays c pointers struct


【解决方案1】:

在destroy_directory 函数中,您释放了数组包含的人员。但是在这个数组中,您没有放置指向结构的指针,而是指向结构本身。因此,您必须释放为数组分配的空间,仅此而已:

    void destroy_directory(struct Directory *directory_ptr) {
       if (directory_ptr->array) {

           free(directory_ptr->array); //<==== Here

           directory_ptr->array = NULL;
           directory_ptr->size = 0;
       }
    }

【讨论】:

  • You cannot use realloc with a string that was not allocated via malloc. So in the initialization function you should use malloc instead of realloc。这不是真的。如果第一个参数是NULL,则realloc 的行为与malloc 完全相同。
  • @emi 你说得对,我认为 OP 在 realloc 中传递了 main 中声明的文字字符串,但它没有。感谢您指出这一点。
  • 编辑后赞成:它比我的更清晰。 @dspr 在初始声明期间在 create_person 中被 NULLified。
【解决方案2】:

person_ptr 是在directory_ptr-&gt;array 分配的内存的一部分。您需要删除此行。

作为黄金法则,分配和释放时负责的内存是相同的。在您的代码中,person 持有者是directory_ptr 内部的array,由add_person 分配。尽管它的名字,它是一个directory 管理器,所以释放它的内存应该只在directorydestroyer 上完成。

【讨论】:

    猜你喜欢
    • 2020-08-04
    • 2021-08-21
    • 2018-08-23
    • 2016-08-08
    • 2014-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-09-05
    • 1970-01-01
    相关资源
    最近更新 更多