亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 5329 | 回復(fù): 7
打印 上一主題 下一主題

[C++] 析構(gòu)函數(shù)內(nèi)存釋放問題 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2015-09-30 19:02 |只看該作者 |倒序?yàn)g覽
本帖最后由 tianhailong 于 2015-09-30 19:25 編輯

今天遇到一個(gè)比較奇怪的問題,沒搞明白,請(qǐng)教一下:
下邊的程序 在構(gòu)造函數(shù)中申請(qǐng)了堆內(nèi)存,析構(gòu)時(shí)釋放,
執(zhí)行了2次構(gòu)造函數(shù),3次析構(gòu)函數(shù),就會(huì)出現(xiàn)對(duì)一塊內(nèi)存兩次釋放,
可是程序還能正常執(zhí)行,也不會(huì)coredump,不知道為什么呢?

#include <iostream>
using namespace std;

class Complex
{
public:
  float realPart;
  float virtualPart;
  char *p;
    Complex (float r, float v)
  {
    realPart = r;
    virtualPart = v;
    p = (char *) malloc (10);
    printf ("Construct %p\n", p);
  }
   ~Complex ()
  {
    free (p);
    printf ("Destruct %p\n", p);
  }
};


Complex
operator - (Complex c)
{
  return Complex (-c.realPart, -c.virtualPart);
}

int
main ()
{
  Complex c1 (11.1f, 22.2f);
  c1 = -c1;
  return 0;
}

執(zhí)行結(jié)果如下:

Construct 0x502010
Construct 0x502030
Destruct 0x502030
Destruct 0x502010
Destruct 0x502030

可以看到,對(duì) 0x502030 做了兩次釋放,我覺得應(yīng)該會(huì)coredump
但是卻沒有

論壇徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龍
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥豬
日期:2014-04-01 08:56:02亥豬
日期:2014-04-08 08:38:58程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-01-05 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-01-07 06:20:00
2 [報(bào)告]
發(fā)表于 2015-09-30 19:57 |只看該作者
執(zhí)行了不止2次的構(gòu)造函數(shù)吧。

你看到2次,是因?yàn)榫幾g器給你構(gòu)造的那個(gè)copy constructor里面沒有print語句。

論壇徽章:
1
2015亞冠之阿爾艾因
日期:2015-08-24 15:46:57
3 [報(bào)告]
發(fā)表于 2015-10-08 10:49 |只看該作者
本帖最后由 何必抱怨 于 2015-10-08 10:51 編輯

事實(shí)上是malloc了一次,然后卻free了兩次。

在vs2008下我試了下,debug模式下是會(huì)報(bào)錯(cuò)的。
在g++ 4.6.3下試了一下,不會(huì)報(bào)錯(cuò)。

事實(shí)上lz的問題等價(jià)于:
  1.         char *p1 = (char *) malloc (10);
  2.         char *p2 = (char *) malloc (10);
  3.         free(p1);
  4.         free(p2);
  5.         free(p1);
復(fù)制代碼
為什么不會(huì)報(bào)錯(cuò)。

我嘗試了一下,如果把上面的代碼改為:
  1.         char *p1 = (char *) malloc (10);
  2.         char *p2 = (char *) malloc (10);
  3.         free(p1);
  4.         free(p1);
復(fù)制代碼
在vs和g++下都會(huì)報(bào)錯(cuò)的。
中間插入了free(p2);之后,vs下會(huì)報(bào)錯(cuò),g++下不會(huì)報(bào)錯(cuò),這個(gè)暫時(shí)不知道什么原因。

論壇徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16賽季CBA聯(lián)賽之江蘇
日期:2017-11-27 11:42:3515-16賽季CBA聯(lián)賽之八一
日期:2017-04-12 14:26:2815-16賽季CBA聯(lián)賽之吉林
日期:2016-08-20 10:43:1215-16賽季CBA聯(lián)賽之廣夏
日期:2016-06-23 09:53:58程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-02-11 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-02-09 06:20:0015-16賽季CBA聯(lián)賽之上海
日期:2015-12-25 16:40:3515-16賽季CBA聯(lián)賽之廣夏
日期:2015-12-22 09:39:36程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-24 06:20:002015亞冠之德黑蘭石油
日期:2015-08-07 09:57:302015年辭舊歲徽章
日期:2015-03-03 16:54:15
4 [報(bào)告]
發(fā)表于 2015-10-08 11:12 |只看該作者
回復(fù) 1# tianhailong


    "undefined behavior" 又不代表一定會(huì)coredump

free.JPG (45.13 KB, 下載次數(shù): 49)

free.JPG

論壇徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16賽季CBA聯(lián)賽之江蘇
日期:2017-11-27 11:42:3515-16賽季CBA聯(lián)賽之八一
日期:2017-04-12 14:26:2815-16賽季CBA聯(lián)賽之吉林
日期:2016-08-20 10:43:1215-16賽季CBA聯(lián)賽之廣夏
日期:2016-06-23 09:53:58程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-02-11 06:20:00程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2016-02-09 06:20:0015-16賽季CBA聯(lián)賽之上海
日期:2015-12-25 16:40:3515-16賽季CBA聯(lián)賽之廣夏
日期:2015-12-22 09:39:36程序設(shè)計(jì)版塊每日發(fā)帖之星
日期:2015-08-24 06:20:002015亞冠之德黑蘭石油
日期:2015-08-07 09:57:302015年辭舊歲徽章
日期:2015-03-03 16:54:15
5 [報(bào)告]
發(fā)表于 2015-10-08 12:28 |只看該作者
本帖最后由 lxyscls 于 2015-10-08 12:29 編輯

回復(fù) 3# 何必抱怨
  1. void
  2. public_fREe(void* mem)
  3. {
  4.   mstate ar_ptr;
  5.   mchunkptr p;                          /* chunk corresponding to mem */

  6.   void (*hook) (__malloc_ptr_t, __const __malloc_ptr_t)
  7.     = force_reg (__free_hook);
  8.   if (__builtin_expect (hook != NULL, 0)) {
  9.     (*hook)(mem, RETURN_ADDRESS (0));
  10.     return;
  11.   }

  12.   if (mem == 0)                              /* free(0) has no effect */
  13.     return;

  14.   p = mem2chunk(mem);

  15.   ... ...

  16.   ar_ptr = arena_for_chunk(p);
  17.   _int_free(ar_ptr, p, 0);
  18. }
復(fù)制代碼
對(duì)于較小的內(nèi)存分配,都在chunk里面分配,使用_init_free()。
  1. static void
  2. _int_free(mstate av, mchunkptr p, int have_lock)
  3. {
  4.   INTERNAL_SIZE_T size;        /* its size */
  5.   mfastbinptr*    fb;          /* associated fastbin */
  6.   mchunkptr       nextchunk;   /* next contiguous chunk */
  7.   INTERNAL_SIZE_T nextsize;    /* its size */
  8.   int             nextinuse;   /* true if nextchunk is used */
  9.   INTERNAL_SIZE_T prevsize;    /* size of previous contiguous chunk */
  10.   mchunkptr       bck;         /* misc temp for linking */
  11.   mchunkptr       fwd;         /* misc temp for linking */

  12.   const char *errstr = NULL;
  13.   int locked = 0;

  14.   size = chunksize(p);

  15.   ... ...

  16.   /*
  17.     If eligible, place chunk on a fastbin so it can be found
  18.     and used quickly in malloc.
  19.   */

  20.   if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())

  21.     ... ...

  22.     set_fastchunks(av);
  23.     unsigned int idx = fastbin_index(size);
  24.     fb = &fastbin (av, idx);

  25.     mchunkptr fd;
  26.     mchunkptr old = *fb;
  27.     unsigned int old_idx = ~0u;
  28.     do
  29.       {
  30.         /* Another simple check: make sure the top of the bin is not the
  31.            record we are going to add (i.e., double free).  */
  32.         if (__builtin_expect (old == p, 0))
  33.           {
  34.             errstr = "double free or corruption (fasttop)";
  35.             goto errout;
  36.           }
復(fù)制代碼
為什么free(p1);free(p1);會(huì)"double free",沒有細(xì)看代碼,我個(gè)人的理解是:兩次取得的chunk_size一樣,所以它認(rèn)為是"double free"。
為什么中間加了一個(gè)free(p2),就不會(huì)"double free"了,是因?yàn)樵賔ree(p1)的時(shí)候,chunk_size變了

因?yàn)閜1,p2的大小都是10,所以它們都在fastbin里面分配;如果把p2設(shè)置成一個(gè)比較大的值,比如13B,free(p1);free(p2);free(p1);一樣會(huì)"double free",因?yàn)閜2分配的chunk和p1不一樣,不影響第二次free(p1)時(shí)候的判斷




論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2015-10-09 17:50 |只看該作者
樓上已經(jīng)回答你的問題了

我只提一下,
你的Complex對(duì)象在調(diào)用operator-傳遞參數(shù)的時(shí)候有拷貝構(gòu)造,此外還有(編譯器自動(dòng)生成的)operator=的調(diào)用,這兩處都是bit-wise的拷貝
如果你的class要管理內(nèi)存,最好實(shí)現(xiàn)所有的copy ctor 和 operator=,否則很容易踩地雷(比如double free)
此外,用引用的方式傳遞函數(shù)參數(shù),避免不必要的構(gòu)造和析構(gòu)

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2015-10-10 20:46 |只看該作者
那段代碼里邊是沒有拷貝構(gòu)造函數(shù)的,只有賦值回復(fù) 6# YEETA


   

論壇徽章:
1
2015亞冠之阿爾艾因
日期:2015-08-24 15:46:57
8 [報(bào)告]
發(fā)表于 2015-10-12 09:07 |只看該作者
回復(fù) 7# tianhailong
編譯器自動(dòng)生成的。


   
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP