new/delete和malloc/free到底有什么区别

news2024/11/24 16:49:58

new和malloc

文章目录

  • new和malloc
  • 前言
  • 一、属性上的区别
  • 二、使用上的区别
  • 三、内存位置的区别
  • 四、返回类型的区别
  • 五、分配失败的区别
  • 六、扩张内存的区别
  • 七、系统调度过程的区别
  • 总结


前言

new和malloc的知识点,作为一个嵌入式工程师是必须要了解清楚的。new和malloc的区别到底在哪里呢

内存分配通常在以下场景下使用:

动态数据结构:如链表、栈、队列和图,这些数据结构的大小在程序运行时可能会变化。
大数据处理:当需要处理大块数据(如图像、文件数据等)时,动态分配可以根据实际需求分配内存。
用户输入:当用户输入的内容大小不可预见时,如读取不定长度的字符串。
资源管理:在需要创建大量对象,但具体数量在编译时无法确定的情况,如对象池或缓存系统。
动态内存分配提供了灵活性,使程序能够有效地管理内存,根据实际需求分配和释放内存。

一、属性上的区别

new/delete:是C++中的关键字(操作符),若要使用,需要编译器支持;
malloc/free:是标准库函数,若要使用则需要引入相应的头文件才可以正常使用。

二、使用上的区别

malloc:申请空间需要显式填入申请内存的大小;
new:无需显式填入申请的内存大小,new会根据new的类型分配内存。

/** malloc/free **/
int  *a  = (int*) malloc(4)free(a)

在这里,malloc(4) 分配了 4 字节的内存。由于 int 类型通常占用 4 字节,因此分配了足够存储一个 int 类型的数据。free 函数用于释放之前通过 malloc 或其他动态内存分配函数分配的内存。在这里,free(a) 释放了指针 a 指向的 4 字节的内存块。

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配内存以存储一个整数
    int *a = (int*) malloc(sizeof(int));
    
    // 检查内存分配是否成功
    if (a == NULL) {
        printf("内存分配失败\n");
        return 1; // 结束程序并返回错误代码
    }
    
    // 设置分配的内存中的值
    *a = 42;

    // 打印内存中的值
    printf("内存中的值是: %d\n", *a);
    
    // 释放分配的内存
    free(a);

    // 将指针设为 NULL,避免悬挂指针
    a = NULL;

    return 0;
}

在这里插入图片描述
在调用 free 函数之前,确保指针确实指向了动态分配的内存是非常重要的。
为什么需要确保指针指向动态分配的内存?
1.内存释放的正确性:
free 函数的作用是释放之前由 malloc、calloc 或 realloc 函数分配的内存。如果指针 a 不指向有效的动态分配内存区域(即没有通过这些函数分配的内存),调用 free(a) 可能会导致未定义行为。未定义行为可能会导致程序崩溃、内存泄漏、数据损坏或其他难以预测的错误。
2.内存管理的安全性:
如果 a 指向非动态分配的内存(比如一个局部变量、全局变量或者静态变量),调用 free 可能会导致操作系统试图释放不属于它的内存,造成错误。例如,如果你试图释放一个未分配的指针或者已经被释放的指针(悬挂指针),这也会导致问题。
确保指针指向动态内存的措施
1.初始化指针:
在使用指针之前,初始化它为 NULL。这样,如果你忘记分配内存,它至少不会指向一个不确定的位置。
例如:int *a = NULL;
分配内存之后检查指针:
每次调用 malloc 或相关函数后,都应该检查指针是否为 NULL。如果为 NULL,说明内存分配失2.败,需要处理这种情况。
2.避免重复释放
确保每个动态分配的内存块只被释放一次。重复释放同一块内存会导致未定义行为。
在释放内存后,可以将指针设置为 NULL,这有助于避免对已经释放内存的重复释放尝试。

free(a);
a = NULL;

3.管理指针的生命周期:
确保在释放内存之前,所有指针操作都合法且在范围内。避免在释放内存后还尝试使用该内存(如访问已释放的内存)。

 // 尝试释放已经释放的指针,安全地检查
    if (a != NULL) {
        free(a); // 这行不会被执行,因为 ma 是 NULL
    }
/** new/delete **/
int *b = new int(0);

分配内存:使用 new 关键字在堆上分配内存来存储一个 int 类型的值。
初始化内存:将这个 int 初始化为 0。
返回指针:new 操作符返回一个指向这块内存的指针,该指针被赋值给 b。
因此,b 是一个指向 int 类型的指针,指向的内存位置存储着值 0。

#include <iostream>

int main() {
    // 使用 new 操作符分配内存并初始化为 0
    int *b = new int(0);
    
    // 输出指针 b 指向的值
    std::cout << "The value of *b is: " << *b << std::endl;
    
    // 修改 b 指向的值
    *b = 42;
    std::cout << "The new value of *b is: " << *b << std::endl;
    
    // 释放分配的内存 避免内存泄漏
    delete b;

    // 将 b 设置为 nullptr,以避免悬挂指针
    b = nullptr;
    
    return 0;
}

在这里插入图片描述

三、内存位置的区别

new:此操作符分配的内存空间是在自由存储区;
malloc:申请的内存是在堆空间。
C/C++的内存通常分为:堆、栈、自由存储区、全局/静态存储区、常量存储区。可能除了自由存储区,其他的内存分布大家应该都比较熟悉。堆:是C语言和操作系统的术语,堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,调用free()归还内存。自由存储区:是C++中动态分配和释放对象的一个概念,通过new分配的内存区域可以称为自由存储区,通过delete释放归还内存。自由存储区可以是堆、全局/静态存储区等,具体是在哪个区,主要还是要看new的实现以及C++编译器默认new申请的内存是在哪里。但是基本上,很多C++编译器默认使用堆来实现自由存储,运算符new和delete内部默认是使用malloc和free的方式来被实现,说它在堆上也对,说它在自由存储区上也正确。因为在C++中new和delete符号是可以重载的,我们可以重新实现new的实现代码,可以让其分配的内存位置在静态存储区等。而malloc和free是C里的库函数,无法对其进行重载。

四、返回类型的区别

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。
malloc内存分配成功则是返回void* ,需要通过强制类型转换将void*指针转换成我们需要的类型。所以在C++程序中使用new会比malloc安全可靠。

五、分配失败的区别

malloc分配内存失败时返回NULL,我们可以通过判断返回值可以得知是否分配成功;
new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL,分配失败时如果不捕捉异常,那么程序就会异常退出。

六、扩张内存的区别

malloc:使用malloc分配内存后,发现内存不够用,那我们可以通过realloc函数来扩张内存大小,realloc会先判断当前申请的内存后面是否还有足够的内存空间进行扩张,如果有足够的空间,那么就会往后面继续申请空间,并返回原来的地址指针;否则realloc会在另外有足够大小的内存申请一块空间,并将当前内存空间里的内容拷贝到新的内存空间里,最后返回新的地址指针。
new:new没有扩张内存的机制。

七、系统调度过程的区别

malloc free是库函数而不是运算符,不在编译器控制范围之内,不能够自动调用构造函数和析构函数。NEW在为对象申请分配内存空间时,可以自动调用构造函数,同时也可以完成对对象的初始化。同理,delete也可以自动调用析构函数。而malloc只是做一件事,只是为变量分配了内存,同理,free也只是释放变量的内存。

总结

new:

int *p = new int(5); // 分配内存并初始化为 5

在 C++ 中使用。
会调用构造函数来初始化对象。
用于分配单个对象或数组。
malloc:

int *p = (int*)malloc(sizeof(int)); // 分配内存,但不初始化

在 C 和 C++ 中使用。
不会调用构造函数,内存中的内容是未定义的。
需要强制转换为目标类型。

  1. 内存释放
    new:使用 delete 或 delete[] 来释放内存。
delete p;       // 对应单个对象
delete[] p;     // 对应对象数组

malloc:使用 free 来释放内存。

free(p);
  1. 异常处理
    new:
    如果内存分配失败,new 会抛出 std::bad_alloc 异常。
    可以使用 new(std::nothrow) 来避免抛出异常,而是返回 nullptr。
    malloc:
    如果内存分配失败,malloc 返回 NULL。不会抛出异常,适用于不支持 C++ 异常的环境。
  2. 适用场景
    new:
    适用于 C++ 编程,特别是当你需要初始化对象或管理对象生命周期时。
    与 C++ 的对象构造和析构机制兼容。
    malloc:
    适用于 C 或者 C++ 中的低级内存管理,尤其是当你在 C++ 环境中需要兼容 C 代码时。
    更适合需要原始内存块的场景,但需要手动处理初始化和类型转换。

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

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

相关文章

驱动器磁盘未格式化危机:专业数据恢复实战指南

认识危机&#xff1a;驱动器中的磁盘未被格式化 在日常的数字生活中&#xff0c;我们时常依赖于各种存储设备来保存重要的文件、照片、视频等数据。然而&#xff0c;当某一天你尝试访问某个驱动器或外接硬盘时&#xff0c;突然弹出的“驱动器中的磁盘未被格式化。您想现在格式…

【CSS in Depth 2 精译_032】5.4 Grid 网格布局的显示网格与隐式网格(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09; 1.1 层叠1.2 继承1.3 特殊值1.4 简写属性1.5 CSS 渐进式增强技术1.6 本章小结 第二章 相对单位&#xff08;已完结&#xff09; 2.1 相对…

利用语义搜索和混合查询策略提升RAG系统的准确性

人工智能咨询培训老师叶梓 转载标明出处 在构建基于大模型&#xff08;LLM&#xff09;的生成式问答系统&#xff08;Generative Q&A&#xff09;时&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;方法被广泛采用。RAG通过结合检索…

Gin渲染

HTML渲染 【示例1】 首先定义一个存放模板文件的 templates文件夹&#xff0c;然后在其内部按照业务分别定义一个 posts 文件夹和一个 users 文件夹。 posts/index.tmpl {{define "posts/index.tmpl"}} <!DOCTYPE html> <html lang"en">&…

【网络通信基础与实践第二讲】包括互联网概述、互联网发展的三个阶段、互联网的组成、计算机网络的体系结构

一、互联网概述 计算机网络是由若干节点&#xff08;node&#xff09;和连接这些节点的链路&#xff08;link&#xff09;组成。 网络之间还可以通过路由器互联起来&#xff0c;这就构成了一个覆盖范围更大的计算机网络。这样的网络称为互联网。 网络把许多计算机连接在一起…

『功能项目』制作提示主角升级面板【56】

我们打开上一篇55事件中心处理怪物死亡的项目&#xff0c; 本章做的事情是制作提示主角升级的界面&#xff0c;当主角升级时就会被显示出来点击确认即可消失 首先在unity编辑场景制作 在确认按钮对象上添加事件 点击Button将Panel添加至事件框选 在事件函数中选择gameobject.S…

【图像拼接】基于SIFT/SURF特征算法的图像拼接,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于SIFT/SURF特征算法的图像拼接&#xff0c;用matlab实现。 一、案例背景和算法介…

[C#学习笔记]Newtonsoft.Json

视频地址&#xff1a;分享一些Newtonsoft.Json的实用功能与技巧_哔哩哔哩_bilibili 强烈推荐学习C#和WPF的朋友关注此UP&#xff0c;知识点巨多&#xff0c;讲解透彻&#xff01; 一、JsonSerializerSettings 1.1 自动缩进-Formatting 使用Formatting.None进行序列化 var …

流媒体之RTMP协议(其四)

欢迎诸位来阅读在下的博文~ 在这里&#xff0c;在下会不定期发表一些浅薄的知识和经验&#xff0c;望诸位能与在下多多交流&#xff0c;共同努力&#xff01; 江山如画&#xff0c;客心如若&#xff0c;欢迎到访&#xff0c;一展风采 文章目录 前期博客参考书籍一、PTMP简介二…

MyBatis的配置文件详解

01-MyBatis的配置文件详解 创建的接口和xml文件的名字最好写一样的要不然会出问题,然后和接口名相同的xml文件在resources下创建个和接口相同文件夹把xml文件放进去,而且resources下的创建的文件夹需要一级一级的创键,比如:cn创建完,创建tulingxue,然后再创建mapper文件夹才行…

python绘制月亮

import matplotlib import matplotlib.pyplot as plt import moviepy.editor as mpymatplotlib.rcParams[font.family] SimHei# 坐标列表 positions [(0, 0), (1 / 4, 1 / 4), (1 / 3, 1 / 4), (1 / 2, 1 / 4), (2 / 3, 1 / 4),(3 / 4, 1 / 4), (1, 1 / 4), (5 / 4, 1 / 4), …

C++中的容器——vector

1. vector的介绍 vector&#xff1a;vector的底层实际上就是一个数组&#xff08;也称为顺序表&#xff09;&#xff0c;数据是连续存储在数组中的&#xff0c;因此vector是可以使用下标来进行访问的&#xff0c;但是它的大小并不是像数组一样是固定的&#xff0c;而是可以动态…

漳州自闭症寄宿学校,孩子的快乐学习乐园

在温暖而包容的南方都市——广州&#xff0c;藏着一所特别的学校&#xff0c;它以爱为名&#xff0c;为自闭症儿童编织了一个充满希望的未来&#xff0c;这就是星贝育园自闭症儿童寄宿制学校。这里&#xff0c;不仅是知识的殿堂&#xff0c;更是孩子们心灵得以自由飞翔、快乐学…

削峰+限流:秒杀场景下的高并发写请求解决方案

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! 哈喽,大家好!我是小米,一个29岁、活泼积极、热衷分享技术的码农。今天和大家聊一聊应对高并发的写请求这个主题,尤其是在大促、秒杀这种场景下,系统…

【Docker Nexus3】maven 私库

1.部署环境 window 11 x64Docker Desktop 4.34.1 (166053) Docker Engine v27.2.0 1.1.Docker 镜像源 1.1.1.Docker Engine 配置 {"builder": {"features": {"buildkit": true},"gc": {"defaultKeepStorage": "32…

微服务_入门2

文章目录 一、Feign二、Gateway服务网关 一、Feign 来看我们以前利用RestTemplate发起远程调用的代码&#xff1a; 存在下面的问题&#xff1a; 代码可读性差&#xff0c;编程体验不统一&#xff08;url需要自己在代码中拼写出来&#xff09;参数复杂URL难以维护&#xff0…

Weapons Armor PBR Pack 1 - Fantasy RPG 武器护甲游戏模型

武器和护甲包#1有30个武器和护甲,每个对象都有默认外观,大多数都有网格变形和Substance Painter源文件,用于自定义纹理。 无限PBR&我的哲学 Infinity PBR是十几位艺术家的作品,他们都在做自己最擅长的事情。我想为独立游戏开发者制作最通用、最优质的资产,按照我希望的…

鸿蒙开发之ArkUI 界面篇 四

文字溢出处理、省略号、文字太长的处理用textOverflow&#xff0c;语法格式是&#xff1a; Text.textOverflow({ overflow: TextOverflow; }) 尤其注意&#xff0c;单独的这个设置没有效果&#xff0c;需要和maxLines一起使用才有效果 Text("男频男频男频男频男频男频男…

好代码网同款wordpress主题,完全开源无加密可二开

这个其实就是好代码网站的早期整站打包代码&#xff0c;当时售价198的&#xff0c;现在里面的部分数据已经过期了&#xff0c;只能展示效果&#xff0c;没法下载。所以就只当做主题分享给大家使用。 资源下载类网站目前还是红利期&#xff0c;搞个特价主机和域名&#xff0c;再…

代码随想录Day 46|动态规划完结,leetcode题目:647. 回文子串、516.最长回文子序列

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 题目题目一&#xff1a;647. 回文子串解题思路&#xff1a;暴力解法动态规划 题目二&#xff1a; 516.最长回文子序列解题思路&#xff1a; 动态规划总结动规五部曲基础概念常见问题类型 动态规划…