免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2097 | 回复: 9
打印 上一主题 下一主题

free() 的問題 [复制链接]

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:03
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-04 22:46 |只看该作者 |倒序浏览
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <malloc.h>
  4.   
  5. int main()
  6. {
  7.        int *ptr = NULL;
  8.        free(ptr);
  9.       return 0;
  10. }
复制代码


為什麼 ptr 沒有 malloc 直接 free(ptr); 也沒問題?

謝謝

论坛徽章:
59
2015年亚洲杯之约旦
日期:2015-01-27 21:27:392015年亚洲杯之日本
日期:2015-02-06 22:09:41拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015元宵节徽章
日期:2015-03-06 15:50:392015年亚洲杯之阿联酋
日期:2015-03-19 17:39:302015年亚洲杯之中国
日期:2015-03-23 18:52:23巳蛇
日期:2014-12-14 22:44:03双子座
日期:2014-12-10 21:39:16处女座
日期:2014-12-02 08:03:17天蝎座
日期:2014-07-21 19:08:47
2 [报告]
发表于 2009-12-04 22:52 |只看该作者

??

MS Free中有判断,但还是不要这样用吧

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:03
3 [报告]
发表于 2009-12-04 23:06 |只看该作者
gcc 也可以编译过去

论坛徽章:
0
4 [报告]
发表于 2009-12-04 23:09 |只看该作者
你非要研究这个,去看free的源码呗

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
5 [报告]
发表于 2009-12-04 23:09 |只看该作者

回复 #1 shihyu 的帖子

free(NULL); 本来就是安全的。

if (ptr) free(ptr);
if (ptr) delete ptr;
都是脱了裤子放屁

论坛徽章:
0
6 [报告]
发表于 2009-12-04 23:29 |只看该作者
在 free(p); 和 delete p; 的内部是进行过判断的,假如为 NULL,就退出来什么都不做。

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:03
7 [报告]
发表于 2009-12-04 23:31 |只看该作者
  1. void
  2. free (void *ptr)
  3. {
  4.   struct header *real;

  5.   /* Determine real implementation if not already happened.  */
  6.   if (__builtin_expect (initialized <= 0, 0))
  7.     {
  8.       if (initialized == -1)
  9.         return;
  10.       me ();
  11.     }

  12.   /* If this is not the correct program just use the normal function.  */
  13.   if (not_me)
  14.     {
  15.       (*freep) (ptr);
  16.       return;
  17.     }

  18.   /* `free (NULL)' has no effect.  */
  19.   if (ptr == NULL)
  20.     {
  21.       catomic_increment (&calls[idx_free]);
  22.       return;
  23.     }

  24.   /* Determine the pointer to the header.  */
  25.   real = ((struct header *) ptr) - 1;
  26.   if (real->magic != MAGIC)
  27.     {
  28.       /* This block wasn't allocated here.  */
  29.       (*freep) (ptr);
  30.       return;
  31.     }

  32.   /* Keep track of number of calls.  */
  33.   catomic_increment (&calls[idx_free]);
  34.   /* Keep track of total memory freed using `free'.  */
  35.   catomic_add (&total[idx_free], real->length);

  36.   /* Update the allocation data and write out the records if necessary.  */
  37.   update_data (NULL, 0, real->length);

  38.   /* Do the real work.  */
  39.   (*freep) (real);
  40. }
复制代码


  /* `free (NULL)' has no effect.  */
  if (ptr == NULL)
    {
      catomic_increment (&calls[idx_free]);
      return;
    }

论坛徽章:
0
8 [报告]
发表于 2009-12-09 20:39 |只看该作者
原帖由 OwnWaterloo 于 2009-12-4 23:09 发表
free(NULL); 本来就是安全的。

if (ptr) free(ptr);
if (ptr) delete ptr;
都是脱了裤子放屁

不能这么说吧,主要是为了安全起见。
#include <malloc.h>
#include <string.h>
int main(int argc,char *argv[])
{
char *p=(char *)malloc(10);
memset(p, 0x03, 10);
printf("bef free 1 p:%p\n", p);
free(p);
printf("aft free 1 p:%p\n", p);
printf("bef free 2\n");
free(p);
printf("aft free 2\n");
return 0;
}


上面代码的输入如下:
[root@myvirfc11 programs]# cc freetest.c
[root@myvirfc11 programs]# ./a.out
bef free 1 p:0x8796008
aft free 1 p:0x8796008
bef free 2
*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x08796008 ***
======= Backtrace: =========
/lib/libc.so.6[0x180231]
./a.out[0x8048507]
/lib/libc.so.6(__libc_start_main+0xe6)[0x126a66]
./a.out[0x80483f1]
======= Memory map: ========
00110000-0027b000 r-xp 00000000 fd:00 204154     /lib/libc-2.10.1.so
0027b000-0027c000 ---p 0016b000 fd:00 204154     /lib/libc-2.10.1.so
0027c000-0027e000 r--p 0016b000 fd:00 204154     /lib/libc-2.10.1.so
0027e000-0027f000 rw-p 0016d000 fd:00 204154     /lib/libc-2.10.1.so
0027f000-00282000 rw-p 0027f000 00:00 0
007f3000-00813000 r-xp 00000000 fd:00 204153     /lib/ld-2.10.1.so
00813000-00814000 r--p 0001f000 fd:00 204153     /lib/ld-2.10.1.so
00814000-00815000 rw-p 00020000 fd:00 204153     /lib/ld-2.10.1.so
0084a000-0084b000 r-xp 0084a000 00:00 0          [vdso]
033c6000-033f0000 r-xp 00000000 fd:00 81401      /lib/libgcc_s-4.4.0-20090506.so.1
033f0000-033f1000 rw-p 00029000 fd:00 81401      /lib/libgcc_s-4.4.0-20090506.so.1
08048000-08049000 r-xp 00000000 fd:00 501482     /home/weiry/programs/a.out
08049000-0804a000 rw-p 00000000 fd:00 501482     /home/weiry/programs/a.out
08796000-087b7000 rw-p 08796000 00:00 0          [heap]
b7ff2000-b7ff4000 rw-p b7ff2000 00:00 0
b8008000-b8009000 rw-p b8008000 00:00 0
bfbf3000-bfc08000 rw-p bffeb000 00:00 0          [stack]
Aborted

可见,free完再次free的话,会出错,比较安全的做法便是:
if (p)
{
free(p);
p = NULL;
}

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
9 [报告]
发表于 2009-12-09 20:45 |只看该作者
原帖由 dreamarm 于 2009-12-9 20:39 发表

不能这么说吧,主要是为了安全起见。
#include
#include
int main(int argc,char *argv[])
{
char *p=(char *)malloc(10);
memset(p, 0x03, 10);
printf("bef free 1 p:%p\n", p);
free(p);
  ...


你跟楼上说的两码事

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2009-12-09 20:48 |只看该作者
原帖由 dreamarm 于 2009-12-9 20:39 发表

不能这么说吧,主要是为了安全起见。
#include
#include
int main(int argc,char *argv[])
{
char *p=(char *)malloc(10);
memset(p, 0x03, 10);
printf("bef free 1 p:%p\n", p);
free(p);
  ...


LZ是free(NULL)
你是两次free  情况不一样吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP