小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

delete p和delete[] p的區(qū)別

 quandsu 2013-04-19

今天在愛立信南京研發(fā)中心筆試碰到一個簡答題為:delete p和delete[] p的區(qū)別,答的不好,下面從網(wǎng)上拷貝一篇文章,來具體說明。

operator new 和 operator delete函數(shù)有兩個重載版本,每個版本支持相關(guān)的new表達式和delete表達式:

void* operator new (size_t);        // allocate an object
void* operator new [] (size_t); // allocate an array

void operator delete (void*); // free an oject
void operator delete [] (void*); // free an array
熟悉C的朋友看到這里可能會很奇怪:
在c中釋放內(nèi)存用free(void *)【注意這里只有一個參數(shù)void *】
為什么到了C++里會出現(xiàn)兩個!按理說delete 會調(diào)用free釋放內(nèi)存的???
另外delete []是如何知道刪除的對象個數(shù)的?

另外一般的教材比如《高質(zhì)量C++編程指南》都會這么說:
在用delete 釋放對象數(shù)組時,留意不要丟了符號‘[]’。例如
delete []objects; // 正確的用法
delete objects; // 錯誤的用法
后者相當于delete objects[0],漏掉了另外99 個對象
這樣的描述當然是錯誤的,而且會誤導觀眾

為了解決問題,打開vc6,輸入以下代碼:
復制代碼
class A
{
private:
int i;
string s;
public:
~A() { printf("hi"); }
};
void d(A *);
int main(int argc, char* argv[])
{
A *p = new A[10];
d(p);
return 0;
}

void d(A *p)
{
delete p;
}
復制代碼
運行結(jié)果:debug assertion failed!
咦,不是說等同于delete p[0]嗎?

為了看看究竟,只好動用那多年以前就忘光了的匯編
經(jīng)過一番折騰,最后連猜帶蒙得出下面的觀點:
1 如果對象無析構(gòu)函數(shù)(包括不需要合成析構(gòu)函數(shù),比如注釋掉~A和string s兩行代碼)
delete會直接調(diào)用operator delete并直接調(diào)用free釋放內(nèi)存
這個時候的new=new [](僅在數(shù)量上有差異),delete=delete[]
2 如果對象存在析構(gòu)函數(shù)(包括合成析構(gòu)函數(shù)),則【這個才是重點】:
new []返回的地址會后移4個字節(jié),并用那4個存放數(shù)組的大小!而new不用后移這四個字節(jié)
delete[]根據(jù)那個4個字節(jié)的值,調(diào)用指定次數(shù)的析構(gòu)函數(shù) ,同樣delete也不需要那四個字節(jié)
結(jié)果就是在不恰當?shù)氖褂胐elete 和delete []調(diào)用free的時候會造成4個字節(jié)的錯位,最終導致debug assertion failed!
再回到《高質(zhì)量C++編程指南》:
delete []objects; // 正確的用法
delete objects; // 錯誤的用法
后者相當于delete objects[0],漏掉了另外99 個對象
嚴格應該這樣說:后者相當于僅調(diào)用了objects[0]的析構(gòu)函數(shù),漏掉了調(diào)用另外99 個對象的析構(gòu)函數(shù),并且在調(diào)用之后釋放內(nèi)存時導致異常(如果存在析構(gòu)函數(shù)的話),如果對象無析構(gòu)函數(shù)該語句與delete []objects相同

注:
1 測試環(huán)境vc6
2 不保證觀點正確
3 歡迎指正

由new分配的一個數(shù)組空間,比如說 int *array=new int[50],當用delete釋放這個空間時,用語句delete []array和delete array是否等價!

C++告訴我們在回收用 new 分配的單個對象的內(nèi)存空間的時候用 delete,回收用 new[] 分配的一組對象的內(nèi)存空間的時候用 delete[]

關(guān)于 new[] 和 delete[],其中又分為兩種情況:(1) 為基本數(shù)據(jù)類型分配和回收空間;(2) 為自定義類型分配和回收空間。

對于 (1),上面提供的程序a可以證明了 delete[] 和 delete 是等同的。
程序a:

復制代碼
#include <stdio.h> 
#define BUFF_SIZE 10240
int main(int argc, char *argv[])
{
printf("Hello, world\n");
char* p = NULL;
while(1)
{
p = new TTT[BUFF_SIZE];
printf("0x%08XH\n",p);
Sleep(5000);
delete p; //或者delete [] p;
p = NULL;
}
return 0;
}
復制代碼

但是對于 (2),情況就發(fā)生了變化。請看下面的程序。

復制代碼
#include <stdio.h> 
#define BUFF_SIZE 10240

class TTT
{
public:
TTT()
{
//aa = new char[1024];
};
~TTT()
{
//delete [] aa;
//printf("TTT destructor()\n");
};
private:
int a;
char* aa;
int inta[1024];
};

int main(int argc, char *argv[])
{
printf("Hello, world\n");
TTT* p = NULL;
while(1)
{
p = new TTT[BUFF_SIZE];
printf("0x%08XH\n",p);
delete p; //delete [] p;
p = NULL;
}
return 0;
}
復制代碼


大家可以自己運行這個程序,看一看 delete p1 和 delete[] p1 的不同結(jié)果,我就不在這里貼運行結(jié)果了。

從運行結(jié)果中我們可以看出,delete p 在回收空間的過程中,只有 p[0] 這個對象調(diào)用了析構(gòu)函數(shù),其它對象如 p[1]、p[2] 等都沒有調(diào)用自身的析構(gòu)函數(shù),在析構(gòu)函數(shù)中的內(nèi)存釋放操作將不會被執(zhí)行(引發(fā)內(nèi)存泄漏),已使用內(nèi)存不斷增加,這就是問題的癥結(jié)所在。如果用 delete[],則在回收空間之前所有對象都會首先調(diào)用自己的析構(gòu)函數(shù),已使用內(nèi)存不會不斷增加。

基本類型的對象沒有析構(gòu)函數(shù),所以回收基本類型組成的數(shù)組空間用 delete 和 delete[] 都是應該可以的;但是對于類對象數(shù)組,只能用 delete[]。對于 new 的單個對象,只能用 delete 不能用 delete[] 回收空間。

測了一下,好像沒有區(qū)別,又想不起在什么地方能用到delete[],大家評論一下。

復制代碼
#include <iostream>; 
#include "xercesc/dom/DOM.hpp"
int main(){

char* pc = 0;
char* pc2;
int i = 21;
pc = new char;
std::cout<<(long)pc<<std::endl;
delete pc;
std::cout<<(long)pc<<std::endl;

pc2 = new char;
std::cout<<(long)pc2<<std::endl;

return 0;
}
復制代碼

輸出:
[root@ts xml]# ./a.out
134519536
134519536
134519536
地址沒有變化,用delete[], delete都一樣


所以一個簡單的使用原則就是:new 和 delete、new[] 和 delete[] 對應使用。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多