2 cailuncailun cailuncailun 于 2016.04.15 10:45 提问

求大神~~ c free()结构体指针出错 25C

本人菜鸟一枚,调试程序时发现下面的程序只要用free()来释放结构体指针就出错,百思不得其解,望大师指正!非常感谢啦!
注:本人用的是VC6.0。自己写的C程序,私心揣测难道是结构体指针特殊一点,或者我释放的方式不对~
补充:C-Free 5.0上选择mingw5调试则没有问题!到底哪里有问题?
图片说明

#include <stdio.h> 
#include <stdlib.h>
#include <malloc.h> 

struct Particle{
     int age;
     double money;
     double famly[4];
     };//定义一个结构体变量 


int main()
{    int PM=5,i,j;
     double *ptr=(double *)calloc(PM,sizeof(double)); 
     struct Particle *swarm=(struct Particle *)calloc(PM,sizeof(struct Particle)); 

     if(swarm==NULL)
     {printf("给swarm申请内存失败!\n");
     exit(1);//异常退出
     }
     else printf("给swarm申请内存成功!\n");

     for(i=0;i<PM;i++,swarm++) //对结构体指针赋值并输出
     {
     swarm->age=2*i;
     swarm->money=3*i+0.55;
       printf("swarm[%d]: age=%d,money=%lf ",i,swarm->age,swarm->money);
     for(j=0;j<4;j++)
        {swarm->famly[j]=1.5*j;printf("%lf ,",swarm->famly[j]);}
     printf("\n");
     }

       printf("\n");//对double型数组赋值并输出
     for(i=0;i<PM;i++)
     printf("%lf\n",ptr[i]+i*0.5);
     printf("\n");

     free(ptr);ptr=0;
     //free(swarm);swarm=NULL;  
     //为什么上面语句一添加程序运行就出问题呢??!!而free(ptr)就没问题? 

     printf("\n\n"); 

} 

4个回答

cailuncailun
cailuncailun   2016.04.15 11:17

哈哈,我已经解决了!问题果然出在指针上!由于这个语句的存在:
for(i=0;i<PM;i++,swarm++) //对结构体指针赋值并输出
因此,一些列操作后,swarm指向的内存已经不再是定义时分配的内存了(大意如此,我可能表达的不太准确),因此直接free()的话就要出错了。
此时,先要将swarm还原,再free: swarm=swarm-PM;free(swarm);swarm=NULL;
更改后就OK啦!
指针ptr之所以不存在这个问题,是因为ptr类似数组名,指向的内存定义后就固定不变,所以可以直接free().
事实上,我也是用ptr去指代一个double型的数组,用指针的优点是这个数组的大小可以用一个变量num来灵活调整。
此处的swarm我认为是一个结构体数组的指针,(swarm+i)相当于将swarm从定义的位置移动了i的某个整数倍,
指向了结构体数组中的下一个成员的地址。

qq_20334059
qq_20334059   2016.04.15 11:09

我试了你的代码,没问题啊。。。

cailuncailun
cailuncailun   2016.04.15 11:20

你直接运行时没有问题,你把//free(swarm);swarm=NULL; 语句前面的\删除了再试试看,我的在vc6.0下运行后报错。

qq_20334059
qq_20334059 好吧,我不是在VC环境下运行的,按道理来讲,就算指针指向的地址变了,释放的话,应该也没问题的才对吧。。。。
一年多之前 回复
cailuncailun
cailuncailun   2016.04.15 11:41

恩,没关系。前几天出了个苦头,C-Free 5 mingw5环境下辛辛苦苦调试通过的程序,准备生成可执行文件时拿到vc6.0下一运行,一堆错误!
感觉vc6.0对代码的要求比较苛刻。还有就是,C的指针用起来真的要小心,要多看理论,否则太容易出错了~
谢谢啦!

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!