A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

3黑马币
# include <stdio.h>
# include <malloc.h>

void g(int * q)
{
        *q = 2000;
        free(q);
}

int main(void)
{
        int * p = (int *)malloc(sizeof(int));
                                           
        *p = 10;

        printf("%d\n", *p);
        g(p);
        printf("%d\n", *p);

        return 0;
}
/*
在VC++6.0中的输出结果为:
————————————————
10
-572662307
————————————————
问题:
   按说在被调函数中将q所指向的内存释放掉后,系统就不存在为p所分配的整型变量地址,
   *p就不允许出现,按之前的经验,出现就会访问冲突,卡死程序,但是这里*p出现了,却可以正常运行?
*/


最佳答案

查看完整内容

是这样的,如果你的g()里面没有free(q)这条语句,那么该程序只是修改了指针p所指向堆内存里的int值,这样输出的结果就是10...2000...这是没有问题的,就算要free,也应该在main函数里的return语句前free,而不是在g()里面做free这个动作,因为你在g()里面给*p赋了值,紧跟着就把P给释放了,也就是把该指针所指向的内存块释放了,那么请问,你又何必做赋值这个动作呢?同时调用完g()后,你又想获得该指针变量所指向的内存值,这是个很危险 ...

8 个回复

倒序浏览
本帖最后由 chenhai 于 2016-2-19 23:00 编辑

        是这样的,如果你的g()里面没有free(q)这条语句,那么该程序只是修改了指针p所指向堆内存里的int值,这样输出的结果就是10...2000...这是没有问题的,就算要free,也应该在main函数里的return语句前free,而不是在g()里面做free这个动作,因为你在g()里面给*p赋了值,紧跟着就把P给释放了,也就是把该指针所指向的内存块释放了,那么请问,你又何必做赋值这个动作呢?同时调用完g()后,你又想获得该指针变量所指向的内存值,这是个很危险的动作,因为在main函数中此时该指针并没有失效,此时所指向的内存地址是随机的,一旦你想通过该地址获取数据,会是不确定的,也就是说你每次执行的时候该指针的地址值随机分配,那么对应的内存输出的值当然也是随机了,可以运行那是你正好访问到了可以访问的内存,,,,,,,,,万一访问到系统地址,则宕机了.....你可以随机输出试试,,,,,,有可能10次都不宕机,但是每次值都不一样,也有可能一次就宕机了,,,,,,,对于用指针来做分配和free,我建议是哪里分配,哪里free,,,尽量不要跨函数free,,,,,这样容易带来管理上的不便........希望可以解答你的疑问.         最后我再补充一点,局部变量的生命周期是随着{}消失而消失的,你在main函数里面定义的变量只有在程序退出时才会消失,你初始化该变量,该变量就是你初始化的值,你不初始化并不意味着该变量没有值,系统会随机分配值给该变量,只是没有显示出来,就拿你上面的程序来说,你就算free了指针P,你不要以为这个指针变量就没有值了,它就消失了,拜托,,,,,它一样有值的,你free的不过是该指针指向的内存空间,不信你可以在free(p),这句代码后面执行printf("%d\n", p);你看看p有没有值,切记是p,而不是*p,,,,,并且每次输出的值会不一样.危险的存在哦,,,,,,,,正确的做法就是一旦该指针不使用了,记得赋值为NULL哦,,,,,,空指针还稍微好点.......
回复 使用道具 举报
释放只是地址里面的值被释放了吧?地址(内存)还在,只是这个地址(内存)里面的值不见了,换成了其他一些随机值了
回复 使用道具 举报
其实就是操作系统回收了该块内存,被系统设置为可再分配资源,也就是说该块内存不归你程序了,你用好了,我要收回来的,下次你再要,我再给你....
回复 使用道具 举报
其实设计这个机制的大牛并不怕你分内存,,,,这点毛线内存算个什么事,他们就怕你分配好不用的时候还不让系统回收,随后把同一根指针再赋值派别的用处了,那完了,原先分配的内存就孤零零的失去索引了,用嘛又没用,回收又不能回收,,,看的难过死了.......哈哈.................................
回复 使用道具 举报
表示看不懂!看来我还需要努力啊
回复 使用道具 举报
void swap(int *p1,int *p2) {   int t=*p1;   *p1=*p2;   *p2=t; } void main() {   int a=1,b=2;   int *pa=&a,*pb=&b;      swap(pa,pb);      ... } 在上面,pa,pb是形参,p1,p2是实参。pa=&a,p1=&a;pb=&b,p2=&b。但pa与p1不是同一个内存区域的指针,pb与p2也一样。摘抄自百度,求给币
回复 使用道具 举报
char *p=NULL;
p=(char*)malloc(10);
strcpy(p,"hello");
free(p);
p=NULL;
假如没有最后一句话,那么就会出现,p仍然是个非空指针,仍然存在,但是指向的内存已经释放,就是说可能已经被其他程序使用和修改过
回复 使用道具 举报
自己运行了20遍,第二个*p值不变.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马