亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区
Chinaunix
標(biāo)題:
析構(gòu)函數(shù)內(nèi)存釋放問題
[打印本頁]
作者:
tianhailong
時間:
2015-09-30 19:02
標(biāo)題:
析構(gòu)函數(shù)內(nèi)存釋放問題
本帖最后由 tianhailong 于 2015-09-30 19:25 編輯
今天遇到一個比較奇怪的問題,沒搞明白,請教一下:
下邊的程序 在構(gòu)造函數(shù)中申請了堆內(nèi)存,析構(gòu)時釋放,
執(zhí)行了2次構(gòu)造函數(shù),3次析構(gòu)函數(shù),就會出現(xiàn)對一塊內(nèi)存兩次釋放,
可是程序還能正常執(zhí)行,也不會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
可以看到,對 0x502030 做了兩次釋放,我覺得應(yīng)該會coredump
但是卻沒有
作者:
fender0107401
時間:
2015-09-30 19:57
執(zhí)行了不止2次的構(gòu)造函數(shù)吧。
你看到2次,是因?yàn)榫幾g器給你構(gòu)造的那個copy constructor里面沒有print語句。
作者:
何必抱怨
時間:
2015-10-08 10:49
本帖最后由 何必抱怨 于 2015-10-08 10:51 編輯
事實(shí)上是malloc了一次,然后卻free了兩次。
在vs2008下我試了下,debug模式下是
會報錯
的。
在g++ 4.6.3下試了一下,
不會報錯
。
事實(shí)上lz的問題等價于:
char *p1 = (char *) malloc (10);
char *p2 = (char *) malloc (10);
free(p1);
free(p2);
free(p1);
復(fù)制代碼
為什么不會報錯。
我嘗試了一下,如果把上面的代碼改為:
char *p1 = (char *) malloc (10);
char *p2 = (char *) malloc (10);
free(p1);
free(p1);
復(fù)制代碼
在vs和g++下都會報錯的。
中間插入了free(p2);之后,vs下會報錯,g++下不會報錯,這個暫時不知道什么原因。
作者:
lxyscls
時間:
2015-10-08 11:12
回復(fù)
1#
tianhailong
"undefined behavior" 又不代表一定會coredump
free.JPG
(45.13 KB, 下載次數(shù): 50)
下載附件
2015-10-08 11:09 上傳
作者:
lxyscls
時間:
2015-10-08 12:28
本帖最后由 lxyscls 于 2015-10-08 12:29 編輯
回復(fù)
3#
何必抱怨
void
public_fREe(void* mem)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
void (*hook) (__malloc_ptr_t, __const __malloc_ptr_t)
= force_reg (__free_hook);
if (__builtin_expect (hook != NULL, 0)) {
(*hook)(mem, RETURN_ADDRESS (0));
return;
}
if (mem == 0) /* free(0) has no effect */
return;
p = mem2chunk(mem);
... ...
ar_ptr = arena_for_chunk(p);
_int_free(ar_ptr, p, 0);
}
復(fù)制代碼
對于較小的內(nèi)存分配,都在chunk里面分配,使用_init_free()。
static void
_int_free(mstate av, mchunkptr p, int have_lock)
{
INTERNAL_SIZE_T size; /* its size */
mfastbinptr* fb; /* associated fastbin */
mchunkptr nextchunk; /* next contiguous chunk */
INTERNAL_SIZE_T nextsize; /* its size */
int nextinuse; /* true if nextchunk is used */
INTERNAL_SIZE_T prevsize; /* size of previous contiguous chunk */
mchunkptr bck; /* misc temp for linking */
mchunkptr fwd; /* misc temp for linking */
const char *errstr = NULL;
int locked = 0;
size = chunksize(p);
... ...
/*
If eligible, place chunk on a fastbin so it can be found
and used quickly in malloc.
*/
if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())
... ...
set_fastchunks(av);
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);
mchunkptr fd;
mchunkptr old = *fb;
unsigned int old_idx = ~0u;
do
{
/* Another simple check: make sure the top of the bin is not the
record we are going to add (i.e., double free). */
if (__builtin_expect (old == p, 0))
{
errstr = "double free or corruption (fasttop)";
goto errout;
}
復(fù)制代碼
為什么free(p1);free(p1);會"double free",沒有細(xì)看代碼,我個人的理解是:兩次取得的chunk_size一樣,所以它認(rèn)為是"double free"。
為什么中間加了一個free(p2),就不會"double free"了,是因?yàn)樵賔ree(p1)的時候,chunk_size變了
因?yàn)閜1,p2的大小都是10,所以它們都在fastbin里面分配;如果把p2設(shè)置成一個比較大的值,比如13B,free(p1);free(p2);free(p1);一樣會"double free",因?yàn)閜2分配的chunk和p1不一樣,不影響第二次free(p1)時候的判斷
作者:
YEETA
時間:
2015-10-09 17:50
樓上已經(jīng)回答你的問題了
我只提一下,
你的Complex對象在調(diào)用operator-傳遞參數(shù)的時候有拷貝構(gòu)造,此外還有(編譯器自動生成的)operator=的調(diào)用,這兩處都是bit-wise的拷貝
如果你的class要管理內(nèi)存,最好實(shí)現(xiàn)所有的copy ctor 和 operator=,否則很容易踩地雷(比如double free)
此外,用引用的方式傳遞函數(shù)參數(shù),避免不必要的構(gòu)造和析構(gòu)
作者:
tianhailong
時間:
2015-10-10 20:46
那段代碼里邊是沒有拷貝構(gòu)造函數(shù)的,只有賦值
回復(fù)
6#
YEETA
作者:
何必抱怨
時間:
2015-10-12 09:07
回復(fù)
7#
tianhailong
編譯器自動生成的。
歡迎光臨 Chinaunix (http://72891.cn/)
Powered by Discuz! X3.2