目录
1、malloc()函数
malloc()函数是 C 语言和 C++ 中的标准库函数之一,该函数原型如下:
#include <stdlib.h>
void* malloc(size_t size);
这个函数的作用是在程序运行时在堆(heap)上分配一块指定大小的内存空间,并返回指向这块内存空间的指针。参数size表示需要分配的内存大小,单位是字节(byte)。
给大家一个实例代码来测试一下:
#include <stdio.h>
#include <stdlib.h> //包含头文件
#include <string.h>
int main()
{
char *ptr = (char *)malloc(strlen("CSDN")+1); //调用malloc函数申请内存
if( NULL == ptr ) //检查内存是否分配成功
{
printf("malloc failure!\n");
return -1;
}
strcpy(ptr,"CSDN"); //使用分配的内存
printf("ptr:%s\n",ptr);
free(ptr); //释放内存
return 0;
}
大家要注意一下,使用malloc分配的内存空间需要手动释放(使用free函数),否则会导致内存泄漏。另外,malloc返回的是void *类型指针,需要进行类型转换为具体类型的指针才能使用。
malloc的作用和基本用法相信大家已经掌握了,那我提出一个问题。上图代码,在使用分配的内存那一块,我将strcpy(ptr,"CSDN");换成ptr = "CSDN";可以吗?为什么?
当运行一下修改的程序,我们发现会报如下的错误:
munmap_chunk(): invalid pointer
Aborted
这是为什么呢?其实很简单,让我们一起来看看吧。该代码通过调用malloc函数从堆中动态分配了一块内存,当我们使用ptr = "CSDN";ptr将指向常量字符串的地址,而不是动态分配的内存空间。所以我们在调用free函数进行释放内存时,因为不能释放常量字符串的内存,所以才会出错。而使用strcpy(ptr,"CSDN");将字符串 "CSDN" 复制到动态分配的内存空间中,然后再使用free进行释放内存。
2、new
new是 C++ 中用于动态分配内存并初始化对象的运算符。它的语法和用法如下:
new 类型名(初始化参数列表)
Type* ptr = new Type; //动态分配单个对象:动态分配一个名为 Type 的对象
,并返回指向该对象的指针 ptr。同时会调用 Type 类的默认构造函数来初始化对象。
Type* arr = new Type[size]; //动态分配对象数组:动态分配一个包含 size 个
Type 类型对象的数组,并返回指向数组首元素的指针 arr。同样会调用 Type 类
的默认构造函数来初始化数组中的每个元素。
和malloc一样,当我们使用完动态分配的内存后,需要进行释放。用malloc函数动态分配的内存我们要用delete进行释放,接下来我们简单讲一下delete怎么使用:
delete ptr; //释放单个对象的内存
delete[] arr; //释放对象数组的内存
ptr、arr必须是new操作的返回值
3、malloc和new的区别
(1)属性
new是C++关键字,需要编译器支持;malloc是库函数,需要头文件支持。
(2)内存区域
new操作符从自由存储区上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。
【自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。】
(3)参数
使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
(4)返回类型
new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
(5)分配失败
new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。