开发者社区> 问答> 正文

C语言结构体成员动态分配内存和释放,释放的时候报错?报错

写了一段程序,执行之后报错

输出信息如下:
“class10.exe”(Win32): 已加载“D:\VSProject\class10\Debug\class10.exe”。已加载符号。
“class10.exe”(Win32): 已加载“C:\Windows\SysWOW64\ntdll.dll”。已加载符号。
“class10.exe”(Win32): 已加载“C:\Windows\SysWOW64\kernel32.dll”。已加载符号。
“class10.exe”(Win32): 已加载“C:\Windows\SysWOW64\KernelBase.dll”。已加载符号。
HEAP[class10.exe]: Invalid address specified to RtlValidateHeap( 00D20000, 00D274AC )
class10.exe 已触发了一个断点。下面是我写的代码:

struct school {
    char address[100];
    char name[30];
};

void printschool(const struct school *s) {
    printf("地址:%s,名称:%s\n", s->address, s->name);
}

void setSchool(struct school *s) {
    strcpy_s(s->address, sizeof(s->address) - 1, "333333");
    strcpy_s(s->name, sizeof(s->name) - 1, "222222");
}
void study9() {
    struct school *p = calloc(1, sizeof(struct school));
    *p->address = calloc(1, sizeof(p->address));
    *p->name = calloc(1, sizeof(p->name));
    strcpy_s(p->address, sizeof(p->address) - 1, "aaa");
    strcpy_s(p->name, sizeof(p->name) - 1, "namenamena");
    printschool(p);
    setSchool(p);
    printschool(p);
    free(p->name);
    free(p->address);
    free(p);
}


 

展开
收起
爱吃鱼的程序员 2020-06-07 17:22:12 1104 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        <pre><code>*p->address = calloc(1, sizeof(p->address));
    

    *p->name = calloc(1, sizeof(p->name)); free(p->name); free(p->address);

    删除这4句

                            为什么删除这四句就可以
    

    如果我不给结构体成员分配内存那结构体成员的内存会自己分配吗

                        <p>楼主的问题是一个非常好的问题,要给楼主点赞。</p>
    

    struct school这种结构体类型为其成员变量address和name分配了大小分别为100和30的内存空间,有了内存空间,因此可以直接使用。

    而struct school_other这种结构体类型并没有为其成员变量分配内存空间,因此在使用之前必须对其分配,才可以为其赋值。

    上述问题,其实可以进一步简化成:这两种变量大家在使用时,应该注意什么?

    char address[100];
    
    char* address_other;
    
    

    address变量已经有了100个字节的内存空间,因此可以直接对其进行赋值,而address_other只是一个指针即只是一个内存地址,而这个地址是多少并未知晓,因此在使用之前,务必要分配内存空间,然后才能使用。

    欲了解更多,欢迎访问:

    https://mp.weixin.qq.com/s?__biz=MzI5MTQ5NDY1MA==&mid=2247484117&idx=1&sn=242d618196c17f735d0b0941ca335202&chksm=ec0e8d40db790456dfc0fb25d29050d31e542dc9e05506b974e7720ca895d1364a41ba49c53d#rd

                        <h4>引用来自“忧郁的小王子”的评论</h4>
    
    *p->address = calloc(1, sizeof(p->address));
    *p->name = calloc(1, sizeof(p->name));
    free(p->name);
    free(p->address);

    删除这4句

    说得没错。

    School 结构 (struct school) 的定义,已经分别为其属性 address 和 name , 以字符数组的形式,定义了空间 100 和30 (单位:字节 )。  因此, 一旦 为此结构找好了指针p :

    struct school *p = calloc(1, sizeof(struct school));,

    其属性 address 和 name 的空间也就随之而搞定了。

    因此,诸如:  

     *p->address = calloc(1, sizeof(p->address));

     *p->name = calloc(1, sizeof(p->name));

    这样的操作,是多(冗)余的。

    值得注意的是,在 我这里的 Dev-Cpp 5.4.0 环境,情况确不同:

    1.  编译时, 只有这两行代码

    *p->address = calloc(1, sizeof(p->address));
    *p->name = calloc(1, sizeof(p->name));

    被警告:[Warning] assignment makes integer from pointer without a cast [enabled by default], 而整个程序编译通过。 

    2.  在成功编译之后。程序能顺利运行。

                        <div class='ref'><h4>引用来自“忧郁的小王子”的评论</h4><pre><code>*p->address = calloc(1, sizeof(p->address));
    

    *p->name = calloc(1, sizeof(p->name)); free(p->name); free(p->address);

    删除这4句

    2020-06-07 17:22:23
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
内存取证与IaaS云平台恶意行 为的安全监控 立即下载
云服务器ECS内存增强型实例re6全新发布 立即下载
对象的生命期管理 立即下载