前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【C++】基础:动态内存与智能指针

【C++】基础:动态内存与智能指针

作者头像
DevFrank
发布2024-07-24 15:44:30
880
发布2024-07-24 15:44:30
举报
文章被收录于专栏:C++开发学习交流

😏1. 知识介绍

C++程序中的内存分为两个部分:(在函数内部声明的所有变量都将使用栈内存)和(程序中未使用的内存,在程序运行时可用于动态分配内存)。

C++ 中,可以使用newdelete运算符为给定类型的变量在运行时分配堆内的内存,这会返回所分配的空间地址。

malloc() 函数在 C 语言中就出现了,在 C++ 中仍然存在,但建议尽量不使用 malloc() 函数。new 与 malloc() 函数相比,其主要的优点是,new 不只是分配了内存,它还创建了对象。

😊2. 动态内存与示例

C++中的动态内存分配是一种在程序运行时按需分配和释放内存的机制。与静态内存(由编译器在编译时分配)和自动内存(由编译器在函数调用时自动分配和释放)不同,动态内存提供了更大的灵活性和控制能力。

动态内存管理需要特别注意以下几点:

  • 必须手动释放通过 new 分配的内存,以防止内存泄漏。
  • 不能重复释放已经释放的内存,这会导致未定义的行为。
  • 动态分配的内存应该在不再使用时及时释放,以避免内存泄漏和资源浪费。

使用动态内存分配时,请确保谨慎操作,避免内存泄漏和悬空指针等问题,并根据需要及时释放动态分配的内存。

double变量示例:

代码语言:javascript
复制
#include <iostream>
using namespace std;
 
int main ()
{
   double* pvalue  = NULL; // 初始化为 null 的指针
   pvalue  = new double;   // 为变量请求内存
 
   *pvalue = 29494.99;     // 在分配的地址存储值
   cout << "Value of pvalue : " << *pvalue << endl;
 
   delete pvalue;         // 释放内存
 
   return 0;
}

二维数组示例:

代码语言:javascript
复制
#include <iostream>
using namespace std;
 
int main()
{
    int **p;   
    int i,j;   //p[4][8] 
    //开始分配4行8列的二维数据   
    p = new int *[4];
    for(i=0;i<4;i++){
        p[i]=new int [8];
    }
 
    for(i=0; i<4; i++){
        for(j=0; j<8; j++){
            p[i][j] = j*i;
        }
    }   
    //打印数据   
    for(i=0; i<4; i++){
        for(j=0; j<8; j++)     
        {   
            if(j==0) cout<<endl;   
            cout<<p[i][j]<<"\t";   
        }
    }   
    //开始释放申请的堆   
    for(i=0; i<4; i++){
        delete [] p[i];   
    }
    delete [] p;   
    return 0;
}

对象创建示例:

代码语言:javascript
复制
#include <iostream>
using namespace std;
 
class Box
{
   public:
      Box() { 
         cout << "调用构造函数!" <<endl; 
      }
      ~Box() { 
         cout << "调用析构函数!" <<endl; 
      }
};
 
int main( )
{
   Box* myBoxArray = new Box[4];
 
   delete [] myBoxArray; // 删除数组
   return 0;
}

😆3. 智能指针与示例

C++智能指针是一种用于自动管理动态分配的内存的指针类模板。它们提供了更安全和方便的方式来管理动态内存,减少内存泄漏和悬空指针等问题。

C++标准库中提供了三种智能指针:std::unique_ptrstd::shared_ptrstd::weak_ptr

std::unique_ptr 是 C++11 引入的智能指针,它具有独占性质。一个 std::unique_ptr 拥有对其所指向对象的唯一所有权,并在其生命周期结束时自动释放内存。

代码语言:javascript
复制
#include <memory>

void uniquePtrExample() {
    std::unique_ptr<int> ptr = std::make_unique<int>(42);
    std::cout << *ptr << std::endl;  // 输出: 42
    // 不需要手动释放内存,当 unique_ptr 离开作用域时会自动释放内存
}

std::shared_ptr 是 C++11 引入的智能指针,可以共享对象的所有权。多个 std::shared_ptr 对象可以同时拥有对同一个对象的所有权,并且会跟踪引用计数。只有当所有 std::shared_ptr 对象都释放了其对对象的所有权时,该对象才会被销毁。

代码语言:javascript
复制
#include <memory>

void sharedPtrExample() {
    std::shared_ptr<int> ptr1 = std::make_shared<int>(42);
    std::shared_ptr<int> ptr2 = ptr1;
    std::cout << *ptr1 << " " << *ptr2 << std::endl;  // 输出: 42 42
    // 不需要手动释放内存,当所有 shared_ptr 离开作用域后才会自动释放内存
}

std::weak_ptr 也是 C++11 引入的智能指针,它用于解决 std::shared_ptr 的循环引用问题。std::weak_ptr 允许你观测一个对象,但不拥有它,因此不会增加引用计数。可以使用 std::weak_ptr 来检查所观测的对象是否已被销毁。

代码语言:javascript
复制
#include <memory>

void weakPtrExample() {
    std::shared_ptr<int> sharedPtr = std::make_shared<int>(42);
    std::weak_ptr<int> weakPtr = sharedPtr;

    if (auto ptr = weakPtr.lock()) {
        // weak_ptr 可以被成功转换为 shared_ptr,表示所观测的对象还存在
        std::cout << *ptr << std::endl;  // 输出: 42
    } else {
        // 所观测的对象已经被销毁
        std::cout << "对象已被销毁" << std::endl;
    }
}

使用智能指针可以简化动态内存管理,减少手动释放内存的繁琐和错误。智能指针的选择取决于具体的需求,例如独占所有权或共享所有权。使用智能指针还可以避免循环引用导致的内存泄漏。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-02-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 😏1. 知识介绍
  • 😊2. 动态内存与示例
  • 😆3. 智能指针与示例
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档