c++基礎教程之指標拷貝詳解
指標是程式設計人員的夢魘,對c語言的開發者是如此,對c++的開發者也是如此。特別是在c++中,如果不注意處理類中的指標,非常容易出問題。如果朋友們不相信可以看看下面的**:
class data
~data()
};
void process()
上面的這段問題有沒有什麼問題?大家可以自己先用筆在草稿紙上面畫一畫。然後上機用實際環境驗證一下。果不其然,系統提示記憶體發生了錯誤。為什麼呢?就是因為記憶體發生了兩次釋放。我們看以看一下process的彙編**:
21: data m(10);
0040105d push 0ah
0040105f lea ecx,[ebp-10h]
00401062 call @ilt+15(data::data) (00401014)
0040106程式設計客棧7 mov dword ptr [ebp-4],0
22: data p = m;
0040106e mov eax,dword ptr [ebp-10h]
00401071 mov dword ptr [ebp-14h],eax
23: }
00401074 lea ecx,[ebp-14h]
00401077 ca @ilt+5(data::~data) (0040100a)
0040107c mov dword ptr [ebp-4],0ffffffffh
00401083 lea ecx,[ebp-10h]
00401086 call @ilt+5(data::~data) (0040100a)
0040108b mov ecx,dword ptr [ebp-0ch]
0040108e mov dword ptr fs:[0],ecx
00401095 pop edi
00401096 pop esi
00401097 pop ebx
00401098 add esp,54h
0040109b cmp ebp,esp
0040109d call __chkesp (004015b0)
004010a2 mov esp,ebp
004010a4 pop ebp
004010a5 ret
21行: data呼叫建構函式,分配記憶體給value
22行: 這裡我們發現程式進行記憶體拷貝,那麼表示m變數value的數值和p變數中value的數值是一樣的
23行:這裡函式即將結束,所以系統呼叫m和p的析構函式,第一次析構的時候value指向的記憶體被釋放,第二次析構的時候由於p變數value的數值非0,所以也需要釋放記憶體,當然也需要進行析構處理,但是此時記憶體已經釋放了,所以記憶體進行了二次釋放,系統報錯。
經過上面的研究,我們發現了問題和原因,那麼應該怎麼解決呢?既然問題是在拷貝函式這裡,那麼就要對拷貝函式進行特殊處理。目前就我個人理解,有兩個方法供大家選擇:
(1)對拷貝建構函式進行private處理,這樣一旦出現了拷貝操作,編譯器就會提示出錯。
clwww.cppcns.comass data
~data()
};(2)編寫拷貝建構函式,進行記憶體深複製
class data
data(const data& d)
~data()
int* get_ptr() const
int get_number() const
};我們看到,經過拷貝建構函式的定義後,原來的process函式解可以正常編譯通過,沒有問題。
本文標題: c++基礎教程之指標拷貝詳解
本文位址:
C 基礎教程之指標
學習 c 的指標既簡單又有趣。通過指標,可以簡化一些 c 程式設計任務的執行,還有一些任務,如動態記憶體分配,沒有指標是無法執行的。所以,想要成為一名優秀的 c 程式設計師,學習指標是很有必要的。例項 include using namespace std int main 當上面的 被編譯和執行時...
C 基礎教程之引用
c 引用 引用變數是乙個別名,也就是說,它是某個已存在變數的另乙個名字。一旦把引用初始化為某個變數,就可以使用該引用名稱或變數名稱來指向變數。c 引用 vs 指標 引用很容易與指標混淆,它們之間有三個主要的不同 不存在空引用。引用必須連線到一塊合法的記憶體。一旦引用被初始化為乙個物件,就不能被指向到...
MySQL基礎教程之IN的用法詳解
mysql in 語法 in 運算子用於 where 表示式中,以列表項的形式支援多個選擇,語法如下 1 2where column in value1,value2,where column not in value1,value2,當 in 前面加上 not 運算子時,表示與 in 相反的意思,...