New和Malloc的使用及其差异

news/2024/7/8 2:09:12

1,new的使用

关于new的定义

new其实就是告诉计算机开辟一段新的空间,但是和一般的声明不同的是,new开辟的空间在堆上,而一般声明的变量存放在栈上。通常来说,当在局部函数中new出一段新的空间,该段空间在局部函数调用结束后仍然能够使用,可以用来向主函数传递参数。另外需要注意的是,new的使用格式,new出来的是一段空间的首地址。所以一般需要用指针来存放这段地址。


#include <iostream>
#include <malloc.h>
using namespace std;
int main(void)
{
   
    int* p = new int;
    *p = 20;
    cout << *p<<endl;
    cout << p << endl; //存放的地址
    delete p;
    int *q = new int(3); //可以在此处赋值
    cout << *q << endl;
    delete q;
    int t = *new int; //这个可以理解成—— new int是 * 然后再加* 不就是 *(*t) = t
    t = 20;
    cout << t << endl;
    
   
    int n = 10; //动态一维数组长度
    int* a = new int[n]; //申请一维动态数组的空间
    int i; //循坏变量

    for (i = 0; i < n; i++) //输入
    {
        a[i] = i;
    }

    for (i = 0; i < n; i++)//输出
    {
        cout << a[i] <<endl;
    }


    return 0;
}

那么你可能会想对于malloc会有free的释放,new也是 具有的吧,的确,new是关于delete的动态内存的释放内存的使用和说明

delete p; //这个是关于delete的使用

delete p; delete p;//两条是不能重复写的,因为内存已经释放掉了,重复写会报错

如果动态分配了一个数组,但是却用delete p的方式释放,没有用[],则编译时没有问题,运行时也一般不会发生错误,但实际上会导致动态分配的数组没有被完全释放。

牢记,用 new 运算符动态分配的内存空间,一定要用 delete 运算符释放。否则,即便程序运行结束,这部分内存空间仍然不会被操作系统收回,从而成为被白白浪费掉的内存垃圾。这种现象也称为“内存泄露”。

如果一个程序不停地进行动态内存分配而总是没有释放,那么可用内存就会被该程序大量消耗,即便该程序结束也不能恢复。这就会导致操作系统运行速度变慢,甚至无法再启动新的程序。但是,只要重新启动计算机,这种情况就会消失。

编程时如果进行了动态内存分配,那么一定要确保其后的每一条执行路径都能释放它

2,malloc的使用

一,malloc的定义:

malloc函数是一种分配长度为num_bytes字节的内存块的函数,可以向系统申请分配指定size个字节的内存空间。malloc的全称是memory allocation(动态内存分配),当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以通过类型转换强制转换为任何其它类型的指针。

二、malloc是什么

malloc其实就是一个可以动态分配内存的函数,从而可以很好的弥补上面静态分配的缺点。

三、malloc怎么使用

1、使用malloc函数的时候,需要包含一个头文件

#include <malloc.h>

2、malloc函数只接受一个形参如,int *p = (int *)malloc(sizeof(int)).先来解释下这句话的含义,int* p代表一个以int类型地址为内容的指针变量,p这个变量占4个字节(某些计算机),这个p变量是静态分配的一个变量。在某些计算机的前提下,指针变量所占的大小都是一样的,无论是char* 还是long *,因为,这些指针变量里面存放的是一个8位16进制的地址,所以占四个字节,当然这些都是在某些计算机的前提下,并不是所有的都是这样的。说道地址的话,就和计算机的地址总线有关,如果计算机的地址总线是32根,每根地址总线只有两种状态(1或0),32根地址线的话,如果全为1的话,刚好就是一个8位十六进制,一位十六进制等于四个二进制(2^4=16)。32根地址总线可以 表示2^10*2^10*2^10*2^2种状态,可以表示的最大内存为4G,也就是说32根地址总线(也就是四个字节 的指针变量)最大可以表示4G内存。malloc函数会返回开辟空间的首地址,加(int *)的目的是让计算机知道,如何去划分这个开辟的空间,因为char、int 、long这些类型的字节大小是不一样的,我们知道了首地址,还要知道是以几个字节为单元。所以,这句话一共开辟了8个字节(某些计算机上),这也是为什么我写sizeof(int),而不是直接写4的原因。

  1. malloc开辟空间所返回的首地址是动态分配的。

四,补充内容

malloc分配的内存大小至少为size参数所指定的字节数

malloc的返回值是一个指针,指向一段可用内存的起始地址

多次调用malloc所分配的地址不能有重叠部分,除非某次malloc所分配的地址被释放掉

malloc应该尽快完成内存分配并返回(不能使用NP-hard的内存分配算法)

实现malloc时应同时实现内存大小调整和内存释放函数(realloc和free)

malloc和free函数是配对的,如果申请后不释放就是内存泄露;如果无故释放那就是什么都没有做,释放只能释放一次,如果释放两次及两次以上会出现错误(但是释放空指针例外,释放空指针其实也等于什么都没有做,所以,释放多少次都是可以的)

五,则有关malloc的释放

free(p);

六,举例

下边的例子仅仅是关于一个一维数组的使用,也可以进行多维数组的使用

int* arr = (int*)malloc(sizeof(int) * n * n);
#include <iostream>
#include <malloc.h>
using namespace std;
int main(void)
{
    int n;
    cout << "请输入n的值:";
    cin >> n;
    //初始化函数的使用
    int* arr = (int*)malloc(sizeof(int) * n);
    int* p = arr;
    for (size_t i = 0; i < n; i++)
    {
        arr[i] = i;
    }

    cout << *p + 3 << endl;

    free(arr);
return 0;
}

3,new和malloc之间的差异

new返回指定类型的指针,并且可以自动计算所需要的大小,但是对于malloc函数是需要你去计算它的长度的sizeof的使用int* arr = (int*)malloc(sizeof(int) * n * n);(二维数组的定义格式)


int *p;
p = new int; //返回类型为int *类型,分配的大小为sizeof(int)
p = new int[100]; //返回类型为int *类型,分配的大小为sizeof(int) * 100
而malloc则必须由我们计算字节数,并且在返回的时候强转成实际指定类型的指针。

而malloc则必须由我们计算字节数,并且在返回的时候强转成实际指定类型的指针。

int *p;
p = (int *)malloc(sizeof(int));

1,malloc的返回是void *,如果我们写成了: p = malloc(sizeof(int));间接的说明了(将void *转化给了int *,这不合理)

2,malloc的实参是sizeof(int),用于指明一个整形数据需要的大小,如果我们写成:

p = (int *)malloc(1), 那么可以看出:只是申请了一个字节的空间,如果向里面存放了一个整数的话,

将会占用额外的3个字节,可能会改变原有内存空间中的数据

3,malloc只管分配内存,并不能对其进行初始化,所以得到的一片新内存中,其值将是随机的。一般意义上:我

们习惯性的将其初始化为NULL。 当然,也可以用memset函数的。

简单的说:

malloc 函数其实就是在内存中:找一片指定大小的空间,然后将这个空间的首地址给一个指针变量,这里的指针变量可以是一个单独的指针,也可以是一个数组的首地址, 这要看malloc函数中参数size的具体内容。我们这里malloc分配的内存空间在逻辑上是连续的,而在物理上可以不连续。我们作为程序员,关注的 是逻辑上的连续,其它的,操作系统会帮着我们处理的。

引用原文链接:https://blog.csdn.net/qq_27871973/article/details/82896847

引用文章:https://www.cnblogs.com/Commence/p/5785912.html


http://lihuaxi.xjx100.cn/news/903452.html

相关文章

华为OD机试 - 最短耗时(JS)

最短耗时 题目 给定一个正整型数组表示待系统执行的任务列表, 数组的每一个元素代表一个任务,元素的值表示该任务的类型。 请计算执行完所有任务所需的最短时间。 任务执行规则如下: 任务可以按任意顺序执行,且每个任务执行耗时间均为1个时间单位。两个同类型的任务之间必…

Java面向对象的特性:封装,继承与多态

Java面向对象的特性 在学习Java的过程是必须要知道的Java三大特性&#xff1a;封装、继承、多态。如果要分为四类的话&#xff0c;加上抽象特性。 封装 1.封装概述 是面向对像三大特征之一&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09; 是面向对象编程语言对客…

使用迭代器遍历List抛出ConcurrentModificationException异常分析。

目录异常复现原因分析例子源码分析解决方案异常复现 使用迭代器对java中List遍历时&#xff0c;程序抛出了ConcurrentModificationException异常。这是由于Java的 fast-fail 机制&#xff08;快速失败&#xff09;导致的&#xff0c;可以提前预料遍历失败情况。看下面的例子。 …

LeetCode-1792. 最大平均通过率【堆,优先队列,贪心】

LeetCode-1792. 最大平均通过率【堆&#xff0c;优先队列&#xff0c;贪心】题目描述&#xff1a;解题思路一&#xff1a;优先队列。首先任何一个班级(x,y)加入一个聪明的学生之后增加的通过率为diff(x1)/(y1)-x/y。那么对p进行堆排序&#xff0c;每次取最大的即可。解题思路二…

19 pandas 分层索引与计算

文章目录分层设置与查询数据index 为有序index 为无序(中文&#xff09;查看数据示例多层索引的创建方式&#xff08;行&#xff09;1、from_arrays 方法2、from_tuples 方法3、from_product 方法多层索引的创建方式&#xff08;列&#xff09;分层索引计算MultiIndex 参数表分…

Linux下的Jenkins安装教程

当前环境 CentOS 7.8Java 11&#xff08;注意当前jenkins支持的Java版本最低为Java11&#xff09;FinalShell 3.9&#xff08;操作环境&#xff09; 安装Jenkins PS&#xff1a;不建议使用Docker安装Jenkins&#xff0c;因为使用Jenkins的时候一般会调用外部程序&#xff0c;…

RabbitMQ 入门到应用 ( 五 ) 应用

6.更多应用 6.1.AmqpAdmin 工具类 可以通过Spring的Autowired 注入 AmqpAdmin 工具类 , 通过这个工具类创建 队列, 交换机及绑定 import org.springframework.amqp.core.AmqpAdmin; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.Di…

华为OD机试 - 静态扫描最优成本(JS)

静态扫描最优成本 题目 静态扫描快速识别源代码的缺陷,静态扫描的结果以扫描报告作为输出: 文件扫描的成本和文件大小相关,如果文件大小为 N ,则扫描成本为 N 个金币扫描报告的缓存成本和文件大小无关,每缓存一个报告需要 M 个金币扫描报告缓存后,后继再碰到该文件则不…