複習C++語法--內存管理

1,描繪內存

2,new/malloc 與 delete/free

new、delete是運算符
malloc()函數只負責留出一塊必定大小的內存,它不知道或關心對象自己。調用new不只會分配正確大小的內存,還會調用相應的構造函數以構建對象。
free()和delete與上面相似,delete會調用析構函數清理對象。數組

3,指針數組的動態內存分配與釋放

const size_t size = 4;
Simple** mySimplePtrArray = new Simple*[size];
for (size_t i = 0; i < size; i++)
{
      mySimplePtrArray[i] = new Simple();
}
for (size_t i = 0; i < size; i++)
{
      delete mySimplePtrArray[i];
}
delete [] mySimplePtrArray;
mySimplePtrArray = nullptr;

4,多維數組的動態內存分配與釋放

char** board = new char[i][j];  // 錯誤!多維數組內存佈局不是連續的,因此基於堆棧的多維數組分配足夠內存的方法是不正確的
// 正確示範
char** allocateCharBoard(size_t x, size_t y)
{
      char** myArray = new char*[x];
      for (size_t i = 0; i < x; i++)
      {
            myArray[i] = new char[y];
      }
      return myArray;
}

void releaseCharBoard(char** myArray, size_t x)
{
      for (size_t i = 0; i < x; i++)
      {
            delete [] myArray[i];
      }
      delete [] myArray;
}

5,智能指針

// 使用標準智能指針unique_ptr和shared_ptr時須要頭文件<memory>

// 建立unique_ptr
void couldBeLeaky()
{
      Simple* mySimplePtr = new Simple();
      mySimplePtr -> go();  // 若是拋出異常,下面delete則不會執行,會致使內存泄漏
      delete mySimplePtr;
}

void notLeaky()
{
      auto mySimpleSmartPtr = make_unique<Simple>();  // 若是構造函數須要參數,放在()裏便可
      mySimpleSmartPtr -> go();
}


// 使用unique_ptr

// a get()方法可用於直接訪問底層指針
void processData(Simple* simple) {};
auto mySimpleSmartPtr = make_unique<Simple>();
processData(mySimpleSmartPtr.get());

// b reset()可釋放底層指針並改爲另外一個指針
mySimpleSmartPtr.reset();  // 釋放並賦值爲nullptr
mySimpleSmartPtr.reset(new Simple());  // 釋放並設置爲一個新指針

// c release()斷開與底層指針的鏈接,將智能指針設置爲nullptr
Simple* simple = mySimpleSmartPtr.release();
delete simple;
simple = nullptr;

// d 建立一個C風格數組
auto arr = make_unique<int[]>(10);
// 建立shared_ptr
auto smartPtr = make_shared<Simple>();

// a 和unique_ptr同樣可用於存儲動態分配的C風格數組的指針
// b 也支持get()和reset(),惟一的區別是當調用reset()時,因爲引用計數,僅在最後的shared_ptr銷燬或重置時才釋放底層資源
// c 不支持release(),可以使用use_count()來檢索同一資源的shared_ptr實例數量
// d 引用計數避免了雙重刪除
相關文章
相關標籤/搜索