動態陣列,注意事項與二維一次性宣告方法
tags:C++
delete 與 delete [] 差異
兩者都會呼叫解構函式,差別在於
後者只會呼叫開頭指標的解構函式
後者只會呼叫開頭指標的解構函式
簡單來說今天你配置了arr[n]的動態陣列
如果你僅使用 delete 那只會解構 arr[0]
後面全部都不會被解到,可怕的是
這並不意味不能編譯與執行。
如果你僅使用 delete 那只會解構 arr[0]
後面全部都不會被解到,可怕的是
這並不意味不能編譯與執行。
為了避免這種情況,記得養好習慣
聽起來很複雜,用一句話概括
方括配方括
這裡如果還不夠明白,簡單測試一下就能馬上了解了
#include <iostream>
class cls{
public:
cls(){ std::cout << "constructor" << std::endl; }
~cls(){ std::cout << "destructor" << std::endl; }
};
int main(){
cls* p = new cls[5];
delete [] p;
return 0;
}
釋放的指標最好手動指向空指標
上面我們可以知道
這裡還有一個小問題,你可以嘗試著把上方的代碼
印出釋放後的指標,你會發現指標沒有指向
這不是太大問題,但是如果造成問題了(肯定會有的
只是用到機率不大),應該不容易被找到問題點
new[]
必須搭配 delete []
這裡還有一個小問題,你可以嘗試著把上方的代碼
印出釋放後的指標,你會發現指標沒有指向
0
這不是太大問題,但是如果造成問題了(肯定會有的
只是用到機率不大),應該不容易被找到問題點
養成習慣最好在釋放後手動指向空指標
空指標這裡簡單的敘述什麼該用什麼
- C 使用
NULL
- C++ 使用 0
- c++11 使用 nullptr
千萬不要因為看起來不重要,且實際實際執行
時確實無法直接看出差別,就忽視了或偷懶
如果你不想 delete 那麼多
可以算出長度,一次宣告出全部
下標仍然可以使用,直接加上就好
void** new2d(int h, int w, int size){
register int i;
void **p;
p = (void**)new char[h*sizeof(void*) + h*w*size];
for(i = 0; i < h; i++)
p[i] = ((char *)(p + h)) + i*w*size;
return p;
}
因此就可以用這 function 動態建立二維陣列
data = (int **)new2d(data_height, data_width, sizeof(int));
可以把他整合到
Macro
上
在程式前頭增加
#define NEW2D(H, W, TYPE) (TYPE **)new2d(H, W, sizeof(TYPE))
便可簡化剛剛動態配置二維陣列寫法
data = NEW2D(data_height, data_width, int);
參考資料
- [問題] 指標 直接存取與使用下標存取 差異
https://www.ptt.cc/bbs/C_and_CPP/M.1472632682.A.DE7.html - 關於指標的new、delete、NULL的觀念問題
http://www.programmer-club.com.tw/showSameTitleN/c/37427.html - C++NEW與DELETE及指標的問題
http://www.programmer-club.com.tw/showSameTitleN/c/28710.html - Re: [心得] 空指標常數(null pointer constant)
https://www.ptt.cc/bbs/C_and_CPP/M.1461824349.A.B47.html
沒有留言:
張貼留言