复习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 引用计数避免了双重删除
相关文章
相关标签/搜索