「C++系列」动态内存

news2024/9/23 10:29:17

【人工智能教程】,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

点击跳转到网站:【人工智能教程】

文章目录

  • 一、动态内存
    • 1. 使用`new`和`delete`
      • ①分配单个对象
      • ②分配对象数组
    • 2. 注意事项
    • 3. 智能指针
    • 4.示例:使用`std::unique_ptr`
  • 二、内存管理函数
    • 1. C语言风格的内存管理函数
    • 2. C++特有的内存管理操作符
    • 3. 智能指针
  • 三、栈内存和堆内存
    • 1. 栈内存(Stack Memory)
    • 2. 堆内存(Heap Memory)
    • 3. 注意事项
    • 4. 结论
  • 四、相关链接

一、动态内存

在C++中,动态内存管理是一个重要的概念,它允许程序在运行时根据需要分配和释放内存。这与静态内存分配(在编译时确定大小)和栈内存分配(在函数调用时自动分配和释放)不同。动态内存分配通常使用newdelete操作符(对于单个对象)或new[]delete[]操作符(对于对象数组)来完成。

1. 使用newdelete

①分配单个对象

int* ptr = new int; // 分配一个int类型的内存空间
*ptr = 10; // 使用该内存空间
delete ptr; // 释放内存
ptr = nullptr; // 避免野指针

②分配对象数组

int* arr = new int[10]; // 分配一个包含10个int的数组
for(int i = 0; i < 10; ++i) {
    arr[i] = i; // 初始化数组
}
delete[] arr; // 释放数组内存
arr = nullptr; // 避免野指针

2. 注意事项

  1. 内存泄漏:如果分配了内存但没有释放,那么这块内存就会一直占用,直到程序结束。这可能导致程序使用的内存不断增加,最终耗尽系统资源。

  2. 野指针:如果释放了内存但没有将指针设置为nullptr,那么这个指针就变成了野指针。尝试通过野指针访问内存是未定义行为,可能导致程序崩溃。

  3. 异常安全:在分配内存后,如果发生异常,那么可能会跳过释放内存的代码。使用智能指针(如std::unique_ptrstd::shared_ptr)可以自动管理内存,提高代码的异常安全性。

3. 智能指针

C++11及以后的版本引入了智能指针,它们可以自动管理内存,减少内存泄漏和野指针的风险。

  • std::unique_ptr:独占式拥有其所指对象,同一时间内只能有一个std::unique_ptr指向给定对象(通过禁止拷贝构造函数和拷贝赋值操作符,只提供移动语义)。

  • std::shared_ptr:允许多个std::shared_ptr实例共享同一个对象。当最后一个拥有该对象的std::shared_ptr被销毁时,对象也会被销毁。

  • std::weak_ptr:一种不拥有其所指对象的智能指针,主要用来解决std::shared_ptr之间循环引用的问题。

4.示例:使用std::unique_ptr

#include <memory>

int main() {
    std::unique_ptr<int> ptr(new int(10));
    // 使用ptr...
    // 当ptr离开作用域时,它指向的内存会自动被释放
    return 0;
}

使用智能指针可以大大简化动态内存的管理,减少错误,提高代码的安全性和可维护性。

二、内存管理函数

在C++中,内存管理主要通过几种方式实现,包括使用C语言风格的内存管理函数以及C++特有的操作符和智能指针。以下是C++中常见的内存管理函数和机制:

1. C语言风格的内存管理函数

这些函数在C++中仍然可以使用,因为它们被C++继承并兼容。

  • malloc:用于动态分配指定大小的内存块。分配的内存不会自动初始化,其内容是不确定的。如果分配成功,返回指向分配的内存的指针;如果失败,返回NULL。
int* ptr = (int*)malloc(sizeof(int));
if (ptr != NULL) {
    // 使用ptr
    free(ptr);
}
  • calloc:类似于malloc,但它会额外将分配的内存初始化为零。它接受两个参数:元素的数量和每个元素的大小。
int* arr = (int*)calloc(10, sizeof(int));
if (arr != NULL) {
    // 使用arr
    free(arr);
}
  • realloc:用于调整之前通过malloc或calloc分配的内存块的大小。如果调整成功,返回指向新内存块的指针(可能与原指针相同,也可能不同);如果失败,返回NULL,并且原内存块保持不变。
int* new_arr = (int*)realloc(arr, 20 * sizeof(int));
if (new_arr != NULL) {
    arr = new_arr;
    // 使用arr
}
free(arr);
  • free:用于释放之前通过malloc、calloc或realloc分配的内存块。同一块内存只能被释放一次,多次释放会导致未定义行为。
free(ptr);

2. C++特有的内存管理操作符

C++引入了newdelete操作符来简化内存管理,并自动处理对象的构造和析构。

  • new:用于动态分配内存,并自动调用对象的构造函数(如果适用)。对于内置类型,它类似于malloc,但不需要类型转换。对于类类型,它还会调用构造函数。
int* ptr = new int;
MyClass* obj = new MyClass;
delete ptr;
delete obj;
  • new[]:用于动态分配一个对象数组的内存,并自动调用数组中每个对象的构造函数(如果适用)。
int* arr = new int[10];
MyClass* objs = new MyClass[5];
delete[] arr;
delete[] objs;
  • delete:用于释放之前通过new分配的内存块,并自动调用对象的析构函数(如果适用)。
  • delete[]:用于释放之前通过new[]分配的内存块,并自动调用数组中每个对象的析构函数(如果适用)。

3. 智能指针

C++11及以后的版本引入了智能指针,如std::unique_ptrstd::shared_ptrstd::weak_ptr,它们可以自动管理内存,减少内存泄漏和野指针的风险。

  • std::unique_ptr:独占式拥有其所指对象,同一时间内只能有一个std::unique_ptr指向给定对象。
  • std::shared_ptr:允许多个std::shared_ptr实例共享同一个对象。当最后一个拥有该对象的std::shared_ptr被销毁时,对象也会被销毁。
  • std::weak_ptr:一种不拥有其所指对象的智能指针,主要用来解决std::shared_ptr之间循环引用的问题。

智能指针通过封装裸指针并提供自动内存管理功能,使得C++中的动态内存管理更加安全和方便。

三、栈内存和堆内存

在C++中,内存管理是一个核心概念,它涉及到如何分配、使用和释放程序运行时所需的内存。C++程序中的内存主要分为几个区域,其中栈内存(Stack Memory)和堆内存(Heap Memory)是最常见的两种。

1. 栈内存(Stack Memory)

栈内存是自动分配和释放的内存区域。它遵循后进先出(LIFO, Last In First Out)的原则。栈内存主要用于存储局部变量、函数参数和返回值等。每当函数被调用时,它的局部变量和参数就会被推入栈中,并在函数返回时从栈中弹出。栈的大小在程序编译时就已经确定,并且通常比堆小得多。

特点

  • 自动管理:不需要程序员手动分配和释放内存。
  • 速度快:由于栈内存的操作简单且高效,访问速度非常快。
  • 有限大小:栈的大小在编译时确定,并且相对较小,可能导致栈溢出(Stack Overflow)错误。

2. 堆内存(Heap Memory)

堆内存是动态分配和释放的内存区域。与栈内存不同,堆内存的大小不是固定的,它可以在程序运行时根据需要动态地增长和缩小。堆内存主要用于存储那些大小在程序编译时未知的对象,或者需要在程序的不同部分之间共享的数据。堆内存的分配和释放需要程序员手动管理,通常使用newdelete操作符(对于单个对象)或new[]delete[]操作符(对于对象数组)来完成。

特点

  • 手动管理:程序员需要负责分配和释放内存,这增加了内存泄漏和野指针的风险。
  • 灵活:堆内存的大小可以在运行时动态变化,适合存储大小未知或变化的数据。
  • 相对较慢:与栈内存相比,堆内存的分配和释放操作更复杂,因此访问速度相对较慢。

3. 注意事项

  • 内存泄漏:在堆上分配的内存如果没有被正确释放,就会导致内存泄漏。随着时间的推移,这可能会耗尽系统的可用内存。
  • 野指针:如果释放了堆上的内存但没有将指针设置为nullptr,那么这个指针就变成了野指针。尝试通过野指针访问内存是未定义行为,可能导致程序崩溃。
  • 栈溢出:如果栈上的局部变量太多或太大,就可能导致栈溢出错误。这通常发生在递归调用过深或局部变量占用大量内存时。

4. 结论

栈内存和堆内存各有优缺点,适用于不同的场景。栈内存适合存储局部变量和函数参数等小量数据,而堆内存则适合存储大量或动态变化的数据。在使用堆内存时,程序员需要格外注意内存的管理,以避免内存泄漏和野指针等问题。

在这里插入图片描述

四、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解
  9. 「C++系列」C++ 修饰符类型
  10. 「C++系列」一篇文章说透【存储类】
  11. 「C++系列」一篇文章讲透【运算符】
  12. 「C++系列」循环
  13. 「C++系列」判断
  14. 「C++系列」函数/内置函数
  15. 「C++系列」数字/随机数
  16. 「C++系列」数组
  17. 「C++系列」字符串
  18. 「C++系列」指针
  19. 「C++系列」引用
  20. 「C++系列」日期/时间
  21. 「C++系列」输入/输出
  22. 「C++系列」数据结构
  23. 「C++系列」vector 容器
  24. 「C++系列」类/对象
  25. 「C++系列」继承
  26. 「C++系列」重载运算符/重载函数
  27. 「C++系列」多态
  28. 「C++系列」数据抽象
  29. 「C++系列」数据封装
  30. 「C++系列」 接口(抽象类)
  31. 「C++系列」文件和流
  32. 「C++系列」异常处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2157308.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解MySQL InnoDB中的B+索引机制

目录 一、InnoDB中的B 树索引介绍 二、聚簇索引 &#xff08;一&#xff09;使用记录主键值的大小进行排序 页内记录排序 页之间的排序 目录项页的排序 &#xff08;二&#xff09;叶子节点存储完整的用户记录 数据即索引 自动创建 &#xff08;三&#xff09;聚簇索引…

[数据结构与算法·C++] 笔记 1.5 流

流 标准输入输出流 标准输入流 cin>>x 读入整型数时以第一个非数字为终结读入字符串时以第一个空格、tab 或换行符为终结 其它方法 标准输出流 cout<<y cout 输出到标准设备cerr 输出错误信息clog 输出错误日志 输出不同进制 hex -> 16 进制dec -> 10 …

windows cuda12.1 pytorch gpu环境配置

安装cuda12.1 nvcc -V conda创建pythong3.10环境 conda create -n llama3_env python3.10 conda activate llama3_env 安装pytorch conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidia gpu - Pytorch version for cuda 12.2 - Stack Ov…

Stable Diffusion WebUI Forge 支持 Flux 了!

大家好&#xff0c;我是每天分享AI应用的萤火君&#xff01; Flux横空出世有段时间了&#xff0c;模型效果也得到了广泛的认可&#xff0c;但是 Stable Diffusion WebUI 官方迟迟没有跟进&#xff0c;据说是因为要修改很多底层的处理机制&#xff0c;加之ComfyUI如火如荼&…

鸿蒙OpenHarmony【轻量系统内核扩展组件(CPU占用率)】子系统开发

基本概念 CPU&#xff08;中央处理器&#xff0c;Central Processing Unit&#xff09;占用率分为系统CPU占用率和任务CPU占用率。 系统CPU占用率&#xff1a;是指周期时间内系统的CPU占用率&#xff0c;用于表示系统一段时间内的闲忙程度&#xff0c;也表示CPU的负载情况。系…

iOS 中 KVC 与 KVO 底层原理

KVC 本质&#xff1a; [object setValue: forKey:];即使没有在.h 文件中有property 的属性声明&#xff0c;setValue:forKey依然会按照上图流程执行代码 KVC 如果成功改变了成员变量&#xff0c;是一定可以被 KVO 监听到成员变量的前后改变的 KVO runtime会生成中间类&…

EmguCV学习笔记 C# 12.3 OCR

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 EmguCV是一个基于OpenCV的开源免费的跨平台计算机视觉库,它向C#和VB.NET开发者提供了OpenCV库的大部分功能。 教程VB.net版本请访问…

ActiveMQ 的消息持久化策略

ActiveMQ 的消息持久化策略 消息持久化对于可靠消息传递来说是一种比较好的方法&#xff0c;即使发送者和接受者不是同时在线&#xff0c;或者消息中心在发送者发送消息后宕机了&#xff0c;消息中心重启后仍然可以将消息发送出去。 消息持久性的原理很简单&#xff0c;就是在发…

[Linux] 通透讲解 什么是进程

标题&#xff1a;[Linux] 通透讲解 什么是进程 个人主页&#xff1a;水墨不写bug &#xff08;图片来自网络&#xff09; 目录 一.深入进程基本概念 二.管理好进程 1.管理好进程的方法 2.描述进程-PCB 3.组织进程 正文开始&#xff1a; 本文按照对进程的先描述再组织进行…

C++之模版的进阶

1.非类型模版参数 模版参数分类类型与非类型形形参 类型形参&#xff1a;出现在模版参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 非类型形参&#xff1a;用一个常亮作为类&#xff08;函数&#xff09;模版的一个参数&#xff0c;在类&#xff08;函数…

股指期货交割方式是什么?

说起股指期货&#xff0c;这可是个高大上的金融玩意儿。咱们平时买卖股票&#xff0c;那是看准了哪只股就下手&#xff0c;赚了就卖&#xff0c;赔了就扛&#xff0c;挺直接的。但股指期货呢&#xff0c;它玩的是未来的预期&#xff0c;就像是你跟人打赌明天天气好不好&#xf…

Fyne ( go跨平台GUI )中文文档-Fyne总览(二)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2​​​​​​​ 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne…

《python语言程序设计》2018版第8章18题几何circle2D类(中部)

第一、重新分析 第一-1、我设计的第一模式第一-1-1、遇到的逻辑分析迷雾第一-1-2、无畏挣扎后的无奈 第二-1、我就把你们两个放到一起,第二-2、我的想法 当我看到了这个2个园并且比对. 第一-1、我设计的第一模式 设计一个最抽象的Circle2D类. 这个类只包含一个x,y和circle 这个…

Parallels Desktop 20 for Mac 推出:完美兼容 macOS Sequoia 与 Win11 24H2

Parallels Desktop 20 for Mac 近日正式发布&#xff0c;这一新版本不仅全面支持 macOS Sequoia 和 Windows 11 24H2&#xff0c;还在企业版中引入了一个全新的管理门户。新版本针对 Windows、macOS 和 Linux 虚拟机进行了多项改进&#xff0c;其中最引人注目的当属 Parallels …

让模型评估模型:构建双代理RAG评估系统的步骤解析

在当前大语言模型(LLM)应用开发的背景下,一个关键问题是如何评估模型输出的准确性。我们需要确定哪些评估指标能够有效衡量提示(prompt)的效果,以及在多大程度上需要对提示进行优化。 为解决这一问题,我们将介绍一个基于双代理的RAG(检索增强生成)评估系统。该系统使用生成代理…

免费开源的AI 智能网盘,图片和媒体管理工具 | 极空间部署『PicHome』

免费开源的AI 智能网盘&#xff0c;图片和媒体管理工具 | 极空间部署『PicHome』 哈喽小伙伴们好&#xff0c;我是Stark-C~ 想必很多小伙伴儿手机&#xff0c;电脑&#xff0c;甚至是网盘上都存取了大量的各类图片&#xff0c;不知道大家都是怎么管理你手头大量的图片的&…

食探秘:Spring Boot校园周边美食发现平台

第三章 系统设计 3.1 系统概要设计 本校园周边美食探索及分享平台选择B/S结构(Browser/Server,浏览器/服务器结构)和基于Web服务两种模式。适合在互联网上进行操作&#xff0c;只要用户能连网&#xff0c;任何时间、任何地点都可以进行系统的操作使用。系统工作原理图如图3-1所…

PMP--二模--解题--71-80

文章目录 13.干系人管理--干系人登记册--记录干系人的身份信息、评估信息、干系人分类。识别完干系人更新干系人登记册。71、 [单选] 一名初级项目经理被指派到一个新启动的项目&#xff0c;高级项目经理指示该初级项目经理去识别在项目中享有既得利益的人员。高级项目经理让初…

上半年营收净利双降,债台高筑下扩产能,天合光能“激进”前行?

近年来&#xff0c;随着新能源产业的蓬勃兴起&#xff0c;以及消费端对低碳经济追求的日益增强&#xff0c;再叠加分布式光伏发电系统的快速发展&#xff0c;全球市场对光伏组件的需求量愈发高涨。 而我国目前又是全球最大的光伏组件生产国和出口国&#xff0c;这离不开隆基绿…

桶排序和计数排序(非比较排序算法)

桶排序 桶排序是一种基于分配的排序算法&#xff0c;特别适合用来排序均匀分布的数据。它的基本思想是将输入的数据分到有限数量的桶里&#xff0c;然后对每个桶内的数据分别进行排序&#xff0c;最后再将各个桶内的数据合并得到最终的排序结果。(通常用于浮点数&#xff0c;因…