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

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「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++编程中的一个重要且复杂的主题。通过合理使用内存分配和释放函数,以及遵循最佳实践,程序员可以编写出高效且健壮的代码。然而,也需要时刻警惕内存泄漏、野指针等潜在问题,以确保程序的稳定性和安全性。


在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WSGI、uwsgi、uWSGI与Nginx

一、写在前 WSGI、uwsgi与uWSGI WSGI (web server gateway interface 网络服务网关接口) 只能用于python&#xff0c;是一个接口标准协议&#xff0c;django、flask自带有uwsgi 是WSGI的通信协议uWSGI是实现了uwsgi协议和WSGI服务的web服务器 他们是为了将web服务器与web框架…

【element ui系列】分享几种实现el-table表格单选的方法

在实际的开发中&#xff0c;经常会用到从表格中选择一条记录的情况&#xff0c;虽然官方给出的例子&#xff0c;但是给人感觉看起来不明显&#xff0c;于是&#xff0c;在此基础上做了改进。接下来&#xff0c;介绍两种常见的实现方法&#xff1a; 1、采用复选框(checkbox)实现…

nodejs批量修改word文档目录样式

工作中遇到一个需求:写个nodejs脚本,对word文档(1000+个)的目录页面进行美化。实现过程遇到不少麻烦,在此分享下。 整体思路 众所周知,Docx格式的Word文档其实是个以xml文件为主的zip压缩包,所以,页面美化整体思路是:先将文档后缀名改为zip并解压到本地,然后将关键的…

信息安全数学基础(40)同态

一、定义 设R和S是两个环&#xff08;或群等其他代数结构&#xff09;&#xff0c;如果存在一个映射σ&#xff1a;R→S&#xff0c;使得对于R中的任意元素a和b&#xff0c;都满足σ(ab)σ(a)σ(b)和σ(ab)σ(a)σ(b)&#xff08;在群的情况下&#xff0c;则满足σ(a*b)σ(a)σ…

【笔面试常见题:三门问题】用条件概率、全概率和贝叶斯推导

1. 问题介绍 三门问题&#xff0c;又叫蒙提霍尔问题&#xff08;Monty Hall problem&#xff09;&#xff0c;以下是蒙提霍尔问题的一个著名的叙述&#xff0c;来自Craig F. Whitaker于1990年寄给《展示杂志》&#xff08;Parade Magazine&#xff09;玛丽莲沃斯莎凡特&#x…

反向代购企业如何精准出击高需求国家——以俄罗斯市场为例

在全球化贸易的浪潮中&#xff0c;中国凭借其强大的工业生产能力、优越的地缘优势以及与俄罗斯日益紧密的双边关系&#xff0c;已成为俄罗斯不可或缺的贸易伙伴。中国制造的商品&#xff0c;从衣食住行到各类消费品&#xff0c;已深深渗透到俄罗斯民众的日常生活中。 据数据统计…

Muse-Ant-Desgin-Vue 改造成 Vite+Vue3

后台地址&#xff1a;https://www.creative-tim.com/product/muse-vue-ant-design-dashboard?refantdv-official 一、配置 ViteAntDesginVue 配置ViteAntDesginVue ViteAntDesginVue配置&#xff1a;https://blog.csdn.net/qq_17523181/article/details/143241626 安装vue-ro…

Proteus中单片机IO口外接LED输出低电平时,引脚却一直保持高电平的问题(已解决)

文章目录 前言解决方法后记 前言 一个排阻接八个 LED&#xff0c;方便又省事&#xff0c;但出现了P1端口输出低电平后&#xff0c;仿真引脚却一直显示红色保持高电平不变&#xff0c;用电压表测量显示 2V 左右。 这是仿真的问题&#xff0c;在用开发板时是不会遇到的&#xff…

DEVOPS: 认证与调度

概述 不知道大家有没有意识到一个现实&#xff0c;就是大部分时候&#xff0c;我们已经不像以前一样通过命令行&#xff0c;或者可视窗口来使用一个系统了现在我们上微博、或者网购&#xff0c;操作的其实不是眼前这台设备&#xff0c;而是一个又一个集群 通常&#xff0c;这样…

Altium Designer使用技巧(一)

一、清除绿色报错。 按TM快捷键。即可消除报错。 二、模块化框选集中。 在原理图中框选原理图&#xff0c;然后按 T S,会跳转到指定pcb&#xff0c;并选择上相应封装&#xff0c;此时按 T O L,再次画一个矩形&#xff0c;刚才选中的封装就会汇集到一起。 三、隐藏飞线 在PCB界面…

笔记本双系统win10+Ubuntu 20.04 无法调节亮度亲测解决

sudo add-apt-repository ppa:apandada1/brightness-controller sudo apt-get update sudo apt-get install brightness-controller-simple 安装好后找到一个太阳的图标&#xff0c;就是这个软件&#xff0c;打开后调整brightness&#xff0c;就可以调整亮度&#xff0c;可…

Unity XR Interaction Toolkit 开发教程(2):导入 SDK【3.0 以上版本】

文章目录 &#x1f4d5;课程总结&#x1f4d5;安装 Unity 编辑器与打包模块&#x1f4d5;导入 OpenXR&#x1f4d5;导入 XR Interaction Toolkit&#x1f4d5;打包发布 获取完整课程以及答疑&#xff0c;工程文件下载&#xff1a; https://www.spatialxr.tech/ 视频试看链接&a…

Python中的字符串“不可改变。/可以改变?”

Python中&#xff0c;规定字符串是“不可变”类型&#xff0c;字符串方法可以“重写”字符串。Python最终让您明白&#xff0c;“字符串不可改变”。&#x1f60e; (笔记模板由python脚本于2024年11月01日 17:55:57创建&#xff0c;本篇笔记适合熟悉python础数据类型str的coder…

5天学习RAG路线图,你信吗?

RAG是"Retrieval Augmented Generation"的缩写&#xff0c;让我们来拆解这个术语&#xff0c;了解RAG的本质&#xff1a; R -> Retrieval&#xff08;检索&#xff09; A -> Augmented&#xff08;增强&#xff09; G -> Generation&#xff08;生成&…

tkinter 走进现代化【一】 - 登录页

import customtkinter as ctk from PIL import Image, ImageTk from tkinter import messagebox import timeclass LoginApp(ctk.CTk):def __init__(self):super().__init__()self.title("登录页面")self.geometry("600x400")self.resizable(False, False)…

实时特征框架的生产实践|得物技术

一、业务背景 使用场景 推荐系统在当今的互联网应用中扮演着至关重要的角色&#xff0c;它极大地丰富了用户体验&#xff0c;帮助用户在海量信息中发现和探索他们可能感兴趣的内容。然而&#xff0c;随着数据量的激增和用户需求的日益多样化&#xff0c;传统的离线推荐系统已…

vue3+vant实现视频播放(含首次禁止进度条拖拽,视频看完后恢复,保存播放视频进度,刷新及下次进入继续播放,判断视频有无全部看完等)

1、效果图 2、 <div><videocontrolsclass"video_player"ref"videoPlayer":src"videoSrc"timeupdate"handleTimeUpdate"play"onPlay"pause"onPause"ended"onVideoEnded"></video><…

【设计模式系列】迭代器模式(七)

一、什么是迭代器模式 迭代器模式&#xff08;Iterator Pattern&#xff09;是一种行为型设计模式&#xff0c;它提供一种方法来顺序访问一个聚合对象中的各个元素&#xff0c;而不暴露其内部的表示。迭代器模式将集合的遍历过程封装在一个独立的迭代器对象中&#xff0c;这样…

硅谷甄选(10)用户管理

用户管理模块 9.1 静态搭建 主要是el-form、el-pagination <template><el-card style"height: 80px"><el-form :inline"true" class"form"><el-form-item label"用户名:"><el-input placeholder"请…

BGP路径属性与路由反射器

前言 IBGP水平分割规则用于防止AS内部产生环路&#xff0c;在很大程度上杜绝了IBGP路由产生环路的可能性&#xff0c;但是同时也带来了新的问题&#xff1a;BGP路由在AS内部只能传递一跳&#xff0c;如果建立IBGP对等体全互联模型又会加重设备的负担。 BGP 路径属性 AS_Path …