C++初阶(6)—— 动态内存开辟函数 C中的malloc calloc realloc free与C++中的new delete delete比较

C中常用的动态内存开辟的函数有malloc,calloc,realloc。我们先来讲解这三个函数的用法。

1.malloc

头文件:#include<stdlib.h>

引用格式:void* malloc(size_t size)

含义: 向内存申请size个字节的空间,并返回该块空间的起始地址。如果开辟失败,将返回NULL
注意默认的返回类型是void*,实际使用时会在malloc前面加上想要强转成的类型

用法举例:

int* p = (int*)malloc(10 * sizeof(int));//可写成(int*)malloc(40);
 
    //malloc申请完之后,必须要检验是否申请成功
    //如果申请失败,将返回一个NULL
    if (p == NULL)
    {
        printf("%s\n", strerror(errno));//将相应的错误码所对应的错误信息打印出来
    }
    else
    {
      //...
    }

2.calloc
头文件:#include<stdlib.h>

引用格式:void* calloc(size_t num,size_t size)
num-元素个数
size-每个元素所占的字节数

含义: 向内存申请numsize个字节的空间,并返回该块空间的起始地址*,并将其中的元素值都初始化成0。如果开辟失败,将返回NULL

用法举例:

 int*p=(int*)calloc(10, sizeof(int));
    if (p = NULL)
    {
        printf("%s\n", strerror(errno));
    }
    else
    {
     //...
    }

3.realloc
头文件:#include<stdlib.h>

引用格式:void* realloc(void*memblock,size_t size)
memblock-要调整的空间的地址
size-调整之后的内存大小(不是新增的大小)

含义:实现扩容,并返回新空间的起始地址。扩容失败时,会返回NULL。
使用该函数有两种情况:

1.如果原申请空间的后面有足够空间可以追加,则直接在原空间后面追加,返回原先的地址
2.如果没有足够的空间可以追加,则realloc函数会重新找一块内存区域,开辟全新的一块满足需求的空间,然后拷贝原申请空间中的内容至新空间,释放原空间,并返回新空间的地址

用法举例:

int main()
{
    int *p=(int*)malloc(20 * sizeof(int));
    if (p == NULL)
    {
        printf("%s\n", strerror(errno));
    }
    else
    {
        //...
    }
    //如果在这里发现20个字节不够用了,想开辟40个字节的空间,就可以用realloc函数调整空间大小
 
    int* ptr=(int*)realloc(p, 40 * sizeof(int));
    //注意!!!扩展空间后,不能直接赋给原来的地址。
    //因为如果申请失败,返回的是null,此时若直接赋给原来的地址,会导致原先地址上的数据丢失
    if (ptr == NULL)
    {
        printf("%s\n", strerror(errno));
    }
    else
    {
      //...
    }

如果将realloc的第一个参数设置成NULL,还可以直接用来开辟空间,此时相当于malloc:

 int* p = realloc(NULL, 40);//等价于malloc(40)

C中常用的动态内存释放的函数是free。对于malloc,realloc,calloc等通过动态内存开辟出来的空间,必须通过free释放

int main()
{
    int* p = (int*)malloc(10 * sizeof(int));
    //当动态申请的空间不再使用时,需要返还空间
    free(p);
    return 0;
}
 

C++中用于动态内存开辟的函数是new.要注意new是操作符,但malloc\calloc\realloc都是函数。
(1)对于内置类型(,char,short,int,float,double,指针等),new与malloc作用上一致,就是写法上有所不同

int main()
{
	//申请一组空间
	//C
	int* p1 = (int*)malloc(sizeof(int) * 10);
	//C++
	int* p2 = new int[10];
	
	//申请单个对象
	//C
	int* p3 = (int*)malloc(sizeof(int));
	//C++ 
	int* p4 = new int;

	//C
	free(p1);
	free(p3);
	//C++
	delete [] p2;
	delete p4;
	return 0;
}

另外,使用new对内置类型开辟空间时,还可以自带初始化 例如:

int* p1 = new int(1);//小括号用于单个数据的赋初值,中括号用于申请多个空间时申明空间大小
int* p2 = new int[4]{ 1,2,3,4 };//不用写等号   

(2)如果针对自定义类型,比如类,malloc只有开辟空间,new包括开辟空间加上构造函数初始化`

class ListNode
{
private:
	int _val;
	ListNode* prev;
	ListNode* next;
public:
	ListNode()
	{
		prev = nullptr;
		next = nullptr;
		_val = 0;
	}
};

int main()
{
	ListNode* p1 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* p2 = new ListNode;
	return 0;
}

在这里插入图片描述
可以看到,p1中的三个成员变量都是随机值,p
2中的都已经按照构造函数初始化完毕了。

C++中常用的动态内存释放的函数是delete。类似的,delete与free的区别是:
对于内置类型两者相同;
对于自定义类型,
free只有释放空间,delete针对自定义类型包括析构函数清理 + 释放空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值