Arrays munmap_chunk():释放数组中的结构时指针无效

Arrays munmap_chunk():释放数组中的结构时指针无效,arrays,c,pointers,struct,Arrays,C,Pointers,Struct,所以我写了一个程序,每当我想添加一些东西的时候,我都必须重新定位一个结构数组。 但是,当我尝试释放数组时,我会单独释放每个元素,但在某个点会得到一个munmap\u chunk():无效指针 以下是完整的代码: #include <stdlib.h> #include <string.h> struct Date { int day; int month; int year; }; struct Person { char *name;

所以我写了一个程序,每当我想添加一些东西的时候,我都必须重新定位一个结构数组。 但是,当我尝试释放数组时,我会单独释放每个元素,但在某个点会得到一个
munmap\u chunk():无效指针

以下是完整的代码:

#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;
}
#包括
#包括
结构日期{
国际日;
整月;
国际年;
};
结构人{
字符*名称;
查*姓;
出生日期;
};
结构目录{
整数大小;
struct Person*数组;
};
结构日期创建_日期(){
结构日期={
.day=0,
.month=0,
.年=0
};
返回日期;
}
结构目录创建_目录(){
结构目录={
.size=0,
.array=NULL
};
返回目录;
}
结构人*创建人(){
结构人*Person_ptr=(结构人*)malloc(sizeof(结构人));
person_ptr->name=NULL;
person_ptr->姓氏=NULL;
返回人;
}
无效副本日期(结构日期*dest,结构日期*src){
dest->day=src->day;
dest->month=src->month;
dest->year=src->year;
}
无效初始化人员(结构人员*人员ptr,字符*姓名,字符*姓氏,结构日期*出生){
if(name!=NULL&&name!=NULL&&birth!=NULL){
person_ptr->name=realloc((*person_ptr).name,(strlen(name)*sizeof(char))+1);
strcpy(人名->姓名);
person_ptr->姓氏=realloc((*person_ptr).姓氏,(strlen(姓氏)*sizeof(char))+1);
strcpy(人名->姓氏、姓氏);
复制日期(&人员->出生,出生);
}
}
无效复制人(结构人*dest,结构人*src){
dest->name=realloc((*dest).name,(strlen(src->name)*sizeof(char))+1);
目的地->姓氏=realloc((*dest).姓氏,(strlen(src->姓氏)*sizeof(char))+1;
struct Date=create_Date();
目的->出生=日期;
strcpy(dest->name,src->name);
strcpy(目的地->姓氏,src->姓氏);
复制日期(&dest->birth,&src->birth);
}
int add_person(结构目录*Directory_ptr,常量结构人*new_person_ptr){
int return_code=0;
目录\u ptr->size++;
directory_ptr->array=realloc(directory_ptr->array,(directory_ptr->size*sizeof(struct Person));
如果(目录\u ptr->数组){
复制人员(&directory人员->数组[目录人员->大小-1],(struct人员*)新建人员人员;
}否则{
返回_代码=1;
}
返回代码;
}
int add_multiple_Person(结构目录*Directory_ptr,常量结构人**persons_ptr,int nb_persons){
对于(int i=0;i姓名);
person_ptr->name=NULL;
免费(个人姓名->姓氏);
person_ptr->姓氏=NULL;
免费(人);
person_ptr=NULL;
}
无效销毁目录(结构目录*目录\u ptr){
如果(目录\u ptr->数组){
对于(int i=0;isize;i++){
销毁_person(&directory_ptr->array[i]);
}
目录\u ptr->array=NULL;
目录\u ptr->size=0;
}
}
内部主(空){
struct Directory Directory=create_Directory();
struct Person*person1=create_Person();
struct Person*person2=create_Person();
struct Person*person3=create_Person();
结构日期={
.day=17,
.月份=04,
.year=1999};
初始化人员(人员1、“Marcel”、“Juan”和日期);
初始化人员(人员2、“阿尔宾”、“米歇尔”和日期);
初始化人员(人员3、“宗主国”、“伯纳德”和日期);
const struct Person*数组[]={
人1,
人2,
人3
};
添加多人(&目录,数组,3);
消灭一人(人1);
消灭某人(人2);
销毁人员(人员3);
销毁_目录(&目录);
返回0;
}
我犯这个错误已经一个多星期了,它一直困扰着我。
如何修复此问题?

在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;
       }
    }
void destroy_目录(结构目录*directory_ptr){
如果(目录\u ptr->数组){
free(directory_ptr->array);//array=NULL;
目录\u ptr->size=0;
}
}

person\u ptr
是在
目录\u ptr->数组中分配的内存的一部分。您需要删除此行


作为黄金法则,内存分配和释放时是一样的。在您的代码中,
人员
持有者是
目录中的
数组
,由
添加人员
分配。尽管名称不同,它是一个
目录
管理器,因此只能在
目录
销毁程序上释放其内存。

您能否澄清在哪一行执行之后会出现错误?错误发生在从销毁目录()调用销毁人员()后的第109行
不能将realloc与未通过malloc分配的字符串一起使用。因此,在初始化函数中,应该使用malloc而不是realloc
。事实并非如此。如果第一个参数是
NULL
realloc
的行为与
malloc
@emi的行为完全相同。你是对的,我以为OP传递了realloc中main声明的文本字符串,但它没有。谢谢你指出这一点。编辑后投票:它比我的更清晰@在初始声明期间,dspr在
create_person
中无效。