从结构中释放内存会产生无效指针

时间:2018-02-12 19:00:09

标签: c

我正在编写一些实验代码,以便更好地使用C, 我在下面写了代码

/*This is a test code. Some of the checks are not performed.*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct person {
    char *name;
    char *occupation;
    int age;
};

typedef struct person prn;

int main(void)
{
    prn *ptr=NULL;
    ptr = malloc(sizeof(ptr));//a node size of prn is created. No need to do malloc(sizeof(prn)) as variable also have same type.
    ptr->name = malloc(sizeof(ptr->name) * ( strlen("Mrigendra") + 1));//
    ptr->occupation = malloc( sizeof( ptr->occupation) * (strlen("SoftwareE")+1) );

    ptr->name = "Mrigendra";//should use memcpy.
    ptr->occupation = "SoftwareE";
    ptr->age = 20;

    printf("%s\n", ptr->name);
    printf("%s\n", ptr->occupation);
    printf("%d\n", ptr->age);

    free(ptr->occupation);
    free(ptr->name);
    free(ptr);
    return 0;

}

执行上述程序后,我收到此错误

Mrigendra
SoftwareE
20
*** Error in `./a.out': free(): invalid pointer: 0x000000000040076e ***
Aborted (core dumped)

我认为ptr指向堆上的位置。 它的成员也是指针并指向堆,所以我释放成员然后释放ptr。

1.我想到的一件事就是&#39;年龄&#39;也在堆,我还没有释放它。这是什么原因?

2.调试它的正确方法是什么? (我担心这是一个愚蠢的问题,或者我错过了一些明显的问题)

3。&#34;核心被倾倒&#34;在哪里?

4 个答案:

答案 0 :(得分:3)

C字符串分配不适用于=运算符。

ptr->name = "Mrigendra";

在此行中,char[]字面值衰减为char*,然后该指针将分配给ptr->name。其他任务也是如此。 malloc编辑的记忆在这里泄露。

当您到达代码中的free语句时,您尝试释放字符串文字的地址,而不是先前分配的内存。

要解决此问题,请使用正确复制内容的功能,例如

strcpy(ptr->name, "Jane");

我错过了第二个错误。阅读this答案以获得解释。由C_Elegans指出

  

sizeof(ptr)需要更改为sizeof(*ptr)

答案 1 :(得分:2)

sizeof(ptr)需要更改为sizeof(*ptr)sizeof(ptr)仅返回计算机上指针的大小,因此当您设置结构的成员时,您会收到堆溢出并可能正在写入malloc的簿记信息

答案 2 :(得分:2)

首先,ptr = malloc(sizeof(ptr))应为ptr = malloc(sizeof(prn)),以便分配足够的内存来保存struct person类型的对象。相反,sizeof(ptr)始终为8(64位系统上指针值的大小)。

其次,ptr->name = malloc(sizeof(ptr->name) * ( strlen("Mrigendra") + 1));应为ptr->name = malloc(strlen("Mrigendra") + 1),以便准确分配内存以保存字符串Mrigendra +字符串终止字符。

第三,使用ptr->name = "Mrigendra"而不是ptr->name,而strcpy(ptr->name,"Mrigendra")指向字符串文字。否则,稍后您将free指向字符串文字的指针,这是未定义的行为。

注意:大多数系统提供的函数malloc代替strcpy + ptr->name=strdup("Mrigendra"),它在一个函数中执行适当的malloc和strcpy。

答案 3 :(得分:2)

ptr = malloc(sizeof(ptr));

以上代码行不会为struct分配足够的内存,您应该使用:

ptr = malloc(sizeof(*ptr));

或类似。

您为struct指针分配内存,但随后,您通过为它们分配字符串文字来覆盖它们的值,从而丢失已分配内存的地址。

所以,现在你有内存泄漏,当你试图对它们调用free()时,你有未定义的行为。您应该使用strcpy()memcpy()等函数来复制字符串,而不是赋值运算符'='