「C/C++」C/C++ 之 动态内存分配

news2024/11/25 6:46:50

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「C/C++」C/C++程序设计
📚全部专栏
「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合
「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发
「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明

目录

    • C/C++ 动态内存管理详解
      • 一、动态内存分配基础
        • 1. C语言中的动态内存分配
        • 2. C++语言中的动态内存分配
      • 二、动态内存的使用
        • 示例:C语言中的动态内存分配
        • 示例:C++语言中的动态内存分配
      • 三、常见错误与陷阱
      • 四、最佳实践
      • 五、结论

C/C++ 动态内存管理详解

在C和C++编程中,内存管理是一个核心且复杂的主题。与静态内存分配(在编译时确定大小)不同,动态内存分配允许程序在运行时根据需要分配和释放内存。这种灵活性带来了强大的功能,但也增加了内存泄漏、野指针等潜在问题的风险。本文将深入探讨C和C++中的动态内存管理,包括内存分配、释放、常见错误以及最佳实践。

一、动态内存分配基础

在C和C++中,动态内存分配主要通过几个标准库函数来实现:

  • C语言:使用malloccallocreallocfree函数。
  • C++语言:除了可以使用C语言的函数外,还可以使用newdelete操作符,以及智能指针(如std::unique_ptrstd::shared_ptr)。
1. C语言中的动态内存分配
  • malloc:分配指定字节数的内存,并返回一个指向该内存的指针。如果分配失败,返回NULL
  • calloc:分配内存并初始化为零。它接受两个参数:元素数量和每个元素的大小(以字节为单位),并返回指向分配内存的指针。
  • realloc:调整先前分配的内存块的大小。它可以增加或减少内存大小,并返回指向新内存块的指针(可能与原指针不同)。如果分配失败,返回NULL,并且原内存块保持不变。
  • free:释放先前通过malloccallocrealloc分配的内存。
2. C++语言中的动态内存分配
  • new:分配内存并调用构造函数(对于类类型)。它返回指向分配对象的指针。如果分配失败,抛出std::bad_alloc异常。
  • delete:释放通过new分配的内存,并调用析构函数(对于类类型)。

C++还引入了智能指针,它们自动管理内存,减少了手动调用delete的需要,从而降低了内存泄漏的风险。

二、动态内存的使用

在C和C++中,动态内存的使用通常涉及以下几个步骤:

  1. 分配内存:使用malloc/calloc/new分配内存。
  2. 使用内存:通过指针访问和操作分配的内存。
  3. 释放内存:使用free/delete释放内存。
示例:C语言中的动态内存分配
#include <stdio.h>
#include <stdlib.h>

int main() {
    int n = 5;
    int *arr = (int *)malloc(n * sizeof(int)); // 分配内存
    if (arr == NULL) {
        // 处理内存分配失败的情况
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }

    // 使用内存
    for (int i = 0; i < n; i++) {
        arr[i] = i * i;
    }

    // 输出数组内容
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    // 释放内存
    free(arr);

    return 0;
}
示例:C++语言中的动态内存分配
#include <iostream>

int main() {
    int n = 5;
    int *arr = new int[n]; // 分配内存

    // 使用内存
    for (int i = 0; i < n; i++) {
        arr[i] = i * i;
    }

    // 输出数组内容
    for (int i = 0; i < n; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;

    // 释放内存
    delete[] arr;

    return 0;
}

三、常见错误与陷阱

  1. 内存泄漏:忘记释放已分配的内存会导致内存泄漏,随着时间的推移,这可能会耗尽系统的可用内存。
  2. 野指针:指向已释放内存的指针或未初始化的指针可能导致未定义行为。
  3. 双重释放:尝试释放同一块内存两次会导致未定义行为。
  4. 越界访问:访问分配内存块之外的内存可能导致程序崩溃或数据损坏。

四、最佳实践

  1. 使用智能指针:在C++中,优先使用智能指针(如std::unique_ptrstd::shared_ptr)来自动管理内存。
  2. 初始化指针:始终将指针初始化为NULL(在C中)或nullptr(在C++中),以避免使用未初始化的指针。
  3. 检查内存分配:在分配内存后,始终检查指针是否为NULL(在C中)或是否抛出异常(在C++中)。
  4. 避免内存泄漏:确保在不再需要内存时释放它。对于C++,使用RAII(资源获取即初始化)模式来管理资源。
  5. 使用工具:使用内存泄漏检测工具(如Valgrind、AddressSanitizer)来检测和修复内存泄漏。

五、结论

动态内存管理是C和C++编程中的一个重要且复杂的主题。通过合理使用内存分配和释放函数,以及遵循最佳实践,程序员可以编写出高效且健壮的代码。然而,也需要时刻警惕内存泄漏、野指针等潜在问题,以确保程序的稳定性和安全性。


在这里插入图片描述

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

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

相关文章

人工智能_神经网络103_感知机_感知机工作原理_感知机具备学习能力_在学习过程中自我调整权重_优化效果_多元线性回归_逻辑回归---人工智能工作笔记0228

由于之前一直对神经网络不是特别清楚,尤其是对神经网络中的一些具体的概念,包括循环,神经网络卷积神经网络以及他们具体的作用,都是应用于什么方向不是特别清楚,所以现在我们来做教程来具体明确一下。 当然在机器学习之后还有深度学习,然后在深度学习中对各种神经网络的…

idea使用Translation插件实现翻译

1.打开idea&#xff0c;settings&#xff0c;选择plugins&#xff0c;搜索插件Translation&#xff0c;安装 2.选择翻译引擎 3.配置引擎&#xff0c;以有道词典为例 3.1 获取应用ID&#xff0c;应用秘钥 3.1.1 创建应用 点击进入有道智云控制台 3.1.2 复制ID和秘钥 3.2 idea设…

Mac下载 安装MIMIC-IV 3.0数据集

参考blog MIMIC IV 3.0数据库安装方法_mimic数据下载-CSDN博客 MIMIC IV数据库安装&#xff08;二&#xff09;_mimic数据库安装-CSDN博客 MIMIC-IV3.0安装_mimic iv 3.0-CSDN博客 MIMIC-IV-v2.0安装教程_mimic iv 安装教程-CSDN博客 MIMIC IV 3.0数据库安装方法或者思路&…

力扣——另一个的子树(C语言)

1.题目&#xff1a; 给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree …

为什么说Tcp是面向字节流的以及(Tcp粘包问题、TCP/UDP对比、listen函数的backlog参数的意义)

为什么说Tcp是面向字节流的&#xff1a; Tcp通信的本质是创建一个tcp的socket&#xff0c;同时就会对应的创建一个发送缓冲区和接收缓冲区。 调用write时, 数据会先写入发送缓冲区中;如果发送的字节数太长, 会被拆分成多个TCP的数据包发出如果发送的字节数太短, 就会先在缓冲…

92.【C语言】数据结构之单向链表的查找,中间插入和删除,销毁

目录 1.链表的查找函数 2.链表的修改函数 3.链表的中间插入函数 1.在pos之前插入:SLTInsertBefore函数 1.借助头指针pphead 示意图 代码示例(写入SList.c) 头文件添加SLTInsertbefore的声明 main.c的部分代码改为 1.测试中间插入 2.测试头部插入 3.测试pos为NULL的…

无人机救援系统基本组成

无人机救援系统基本组成 1. 源由2. 组成2.1 无人机载具2.1.1 多旋翼2.1.2 垂起固定翼2.1.3 智能避障2.1.4 物资投递 2.2 智能吊舱2.2.1 云台2.2.2 高清摄像2.2.3 红外热成像2.2.4 激光测距2.2.5 目标跟踪 2.3 通讯链路2.3.1 超长距离通信2.3.2 长距离通信2.3.3 中等距离通信 2.…

普通高考预报名上传蓝底证件照手机自拍方法详解

普通高考预报名过程中&#xff0c;上传一张合规的蓝底证件照是必不可少的一步。本文将详细介绍如何使用手机自拍并使用工具来制作符合要求的蓝底证件照。注意&#xff0c;目前仅有广东等个别省份允许特定类型考生使用自拍照上传&#xff08;例如普高预报名阶段、学考报名&#…

linux 原子操作

首先是为什么要有 原子操作 网上的截图&#xff1a; 不能从C语言来看&#xff0c;要从汇编来看 但是实际的情况有可能是这样。 A进程没有得到想要的结果。 然后是 原子操作的 底层实现 最终会是这段代码&#xff0c;当然只是一个 加一的操作。 static inline void atomic_a…

ComfyUI新神器ComfyUI-Detail-Daemon:一键提升AI绘画细节,Flux模型画质再升级

近日&#xff0c;一款名为ComfyUI-Detail-Daemon的革命性插件正在AI绘画圈引起轰动。这款由Jonseed开发的工具&#xff0c;巧妙地将sd-webui-Detail-Daemon移植到ComfyUI平台&#xff0c;为创作者们带来了前所未有的细节优化体验。 这款插件最引人注目的特点是其强大的细节增强…

Qt/C++地图导航app/支持qml/手机运行/输入起点终点规划路径/模拟轨迹移动

一、前言说明 搞Qt地图开发这块&#xff0c;随着研究的深入&#xff0c;用户的需求变化&#xff0c;最近又需要在手机上运行&#xff0c;由于本地图组件依赖浏览器控件&#xff0c;而手机安卓上的Qt并没有带qwebengine控件&#xff0c;怎么办呢&#xff0c;不断的努力验证下&a…

优优嗨聚集团:正确了解个人债务过多的危害

在当今社会&#xff0c;随着消费观念的转变和金融产品的多样化&#xff0c;个人债务问题日益凸显。许多人为了追求更高的生活质量或应对突发情况&#xff0c;不自觉地陷入了债务的泥潭。然而&#xff0c;个人债务过多不仅会影响个人的财务状况&#xff0c;还可能对生活和心理产…

Pycharm,2024最新版Pycharm现在安装环境配置汉化详细教程!

码&#xff08;文末附带精品籽料&#xff09;&#xff1a; K384HW36OBeyJsaWNlbnNlSWQiOiJLMzg0SFczNk9CIiwibGljZW5zZWVOYW1lIjoibWFvIHplZG9uZyIsImxpY2Vuc2VlVHlwZSI6IlBFUlNPTkFMIiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IiIsIm…

聚水潭数据集成MySQL:高效组合装商品查询案例

聚水潭数据集成到MySQL&#xff1a;组合装商品查询案例分享 在现代企业的数据管理中&#xff0c;如何高效、准确地实现不同系统之间的数据集成是一个关键问题。本文将聚焦于一个具体的技术案例&#xff1a;将聚水潭的组合装商品数据集成到MySQL数据库中&#xff0c;以便在BI狄…

MYSQL多表查询、函数、索引和事务思维导图

MySQL多表查询和函数 MySQL窗口函数 MySQL循环、游标、索引、事务

Vue3 学习笔记(八)Vue3 语法-Class 与 Style绑定详解

在 Vue.js 中&#xff0c;动态地绑定 CSS 类和样式是一项常见的需求。Vue 提供了几种不同的方法来实现这一点&#xff0c;包括对象语法、数组语法和组件的作用域插槽。 以下是这些方法的详细说明&#xff1a; 一、Class 绑定 1、对象语法 对象语法允许根据表达式的真值动态地切…

头歌——人工智能(机器学习 --- 决策树2)

文章目录 第5关&#xff1a;基尼系数代码 第6关&#xff1a;预剪枝与后剪枝代码 第7关&#xff1a;鸢尾花识别代码 第5关&#xff1a;基尼系数 基尼系数 在ID3算法中我们使用了信息增益来选择特征&#xff0c;信息增益大的优先选择。在C4.5算法中&#xff0c;采用了信息增益率…

WPF+Mvvm案例实战(五)- 自定义雷达图实现

文章目录 1、项目准备1、创建文件2、用户控件库 2、功能实现1、用户控件库1、控件样式实现2、数据模型实现 2、应用程序代码实现1.UI层代码实现2、数据后台代码实现3、主界面菜单添加1、后台按钮方法改造&#xff1a;2、按钮添加&#xff1a;3、依赖注入 3、运行效果4、源代码获…

【CSS】——基础入门常见操作

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;CSS引入 二&#xff1a;CSS对元素进行美化 1&#xff1a;style修饰 2&#xff1a;选…

Jmeter基础篇(19)JSR223预处理器

前言 JSR223预处理器是Apache JMeter中的一个组件&#xff0c;它允许用户使用任何支持Java Scripting API (JSR 223) 的脚本语言来执行预处理任务。这个功能非常强大&#xff0c;因为它让测试人员能够利用如Groovy、JavaScript&#xff08;Nashorn引擎&#xff09;、BeanShell…