日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深拷贝拯救指针重复释放(浅拷贝)造成的内存泄漏

發布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深拷贝拯救指针重复释放(浅拷贝)造成的内存泄漏 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 淺拷貝以及內存泄漏的背景

先考慮一種情況,對一個已知對象進行拷貝,編譯系統會自動調用一種構造函數——拷貝構造函數,如果用戶未定義拷貝構造函數,則會調用默認拷貝構造函數

#include <iostream> #include "student.h" int main() {Student s1;Student s2(s1);//Student s2 = s1;//復制對象return 0; } //仔細看,對象中存在一個指針成員,這個是我們研究的核心#ifndef STUDENT_H #define STUDENT_H class Student {private:int num;char *name;public:Student();~Student(); };#endif // 注意看析構函數,我們對對象的指針成員進行內存的釋放 #include "student.h" #include <iostream> using namespace std;Student::Student() {name = new char(20);cout << "Student" << endl;} Student::~Student() {cout << "~Student " << (int)name << endl;delete name;name = NULL; }

執行結果:調用一次構造函數,調用兩次析構函數,兩個對象的指針成員所指內存相同,這會導致什么問題呢?

name指針被分配一次內存,但是程序結束時該內存卻被釋放了兩次,會造成內存泄漏問題!

這是由于編譯系統在我們沒有自己定義拷貝構造函數時,會在拷貝對象時調用默認拷貝構造函數,進行的是淺拷貝!即對指針name拷貝后會出現兩個指針指向同一個內存空間

所以,在對含有指針成員的對象進行拷貝時,必須要自己定義拷貝構造函數,使拷貝后的對象指針成員有自己的內存空間,即進行深拷貝,這樣就避免了內存泄漏發生。

2. 深拷貝進行內存泄漏進行拯救

//student.h#ifndef STUDENT_H #define STUDENT_H class Student {private:int num;char *name;public:Student();//構造函數~Student();//析構函數Student(const Student &s); //重要:拷貝構造函數,const防止對象被改變 };#endif //student.cpp#include "student.h" #include <iostream> #include <string.h> using namespace std;Student::Student() {name = new char(20);cout << "Student " << endl; }Student::~Student() {cout << "~Student " << (int)name << endl;delete name;name = NULL; }Student::Student(const Student &s) {name = new char(20); // 對于每一次對象的引用,我們都重新開辟內存空間memcpy(name, s.name, strlen(s.name));cout << "copy Student " << endl; }

執行結果:調用一次構造函數,一次自定義拷貝構造函數,兩次析構函數。兩個對象的指針成員所指內存不同。

總結:淺拷貝只是對指針的拷貝,拷貝后兩個指針指向同一個內存空間,深拷貝不但對指針進行拷貝,而且對指針指向的內容進行拷貝,經深拷貝后的指針是指向兩個不同地址的指針。

再說幾句:

當對象中存在指針成員時,除了在復制對象時需要考慮自定義拷貝構造函數,還應該考慮以下兩種情形:

1.當函數的參數為對象時,實參傳遞給形參的實際上是實參的一個拷貝對象,系統自動通過拷貝構造函數實現;

2.當函數的返回值為一個對象時,該對象實際上是函數內對象的一個拷貝,用于返回函數調用處。

3. 參考文獻

《C++ primer》

總結

以上是生活随笔為你收集整理的深拷贝拯救指针重复释放(浅拷贝)造成的内存泄漏的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。