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

C 从结构释放内存会产生无效指针,c,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; }; type

我正在写一些实验性的代码,为了更好地掌握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;

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

1.我想到的一件事是,“年龄”也在堆上,我还没有释放它。这是原因吗

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


3.“堆芯倾倒”的位置?

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

C-string赋值不适用于
=
运算符

ptr->name = "Mrigendra";
在这一行中,
char[]
文本衰减为
char*
,然后该指针被分配到
ptr->name
。你其余的作业也是如此。您
malloc
ed的内存在此泄漏

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

要解决这个问题,请使用适当复制内容的函数,如

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

我错过了第二个错误。阅读答案以获得解释。正如所指出的

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

首先,
ptr=malloc(sizeof(ptr))
应该是
ptr=malloc(sizeof(prn))
,以便分配足够的内存来容纳
struct person类型的对象<相反,code>sizeof(ptr)
总是
8
(64位系统上指针值的大小)

其次,
ptr->name=malloc(sizeof(ptr->name)*(strlen(“Mrigendra”)+1)
应该是
ptr->name=malloc(strlen(“Mrigendra”)+1)
以便准确分配内存来保存字符串
Mrigendra
+字符串终止字符

第三,使用strcpy(ptr->name,“Mrigendra”)代替让
ptr->name
指向字符串文本的
ptr->name=“Mrigendra>。否则,稍后将
释放
指向字符串文字的指针,这是未定义的行为

注意:大多数系统提供的函数不是
malloc
+
strcpy
,而是
ptr->name=strdup(“Mrigendra”)
,它在一个函数中执行适当的malloc和strcpy

ptr = malloc(sizeof(ptr));
上述代码行无法为
结构分配足够的内存,应改为使用:

ptr = malloc(sizeof(*ptr));
或类似的

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


因此,现在出现内存泄漏,当您尝试调用
free()
时,您有未定义的行为。您应该使用诸如
strcpy()
memcpy()
之类的函数来复制字符串,而不是赋值运算符
'='

您的分配代码非常奇怪。为什么要乘以指针的大小?将其更改为
sizeof(*ptr)
和其他位置。您需要的是指针对象的大小。
ptr=malloc(sizeof(ptr))是错误的。分配4或8个字节(指针大小)的。您需要分配
sizeof(prn)
,就像您的注释所说的那样。是的,ptr不是prn,它是指向prn的指针。这些是非常不同的事情。是的,您应该使用memcpy()或strcpy()来分配字符串成员,因为为它们分配内存,然后将它们分配给字符串常量是一种即时内存泄漏。
ptr=malloc(sizeof(ptr))//将创建prn的节点大小。不需要使用malloc(sizeof(prn))作为变量,因为变量也具有相同的类型。
这是不必要的,请使用
ptr=malloc(sizeof(*ptr))。但是为什么要为单个
结构分配内存,除非您计划稍后重新分配以获得更多容量?您使用的是什么工具链?其他人已经告诉您代码出了什么问题,但您应该使用调试器进入其中,并实际查看它在做什么。您需要在每个步骤中转储局部变量。当我为ptr释放内存时,“age”变量也会被释放吗?是的,
free(ptr)
将释放完整的
struct person
-对象,该对象由两个指针值和一个int值组成。
ptr = malloc(sizeof(*ptr));