1) 请解释new和malloc的区别,并分别解释他们的用法
1.(从名字角度)malloc是C语言的标准库函数,new是运算符(sizeof也是运算符)
malloc是C语言的标准库函数,在stdlib.h头文件中声明。它的全称为"memory allocation"(内存分
配),用于在堆上动态地分配指定字节数的内存空间。
new是C++中的操作符,用于在C++中动态创建对象或数组,其语法更符合C++的面向对象特性。
2.(从返回值角度)malloc的返回值必须强转,new的返回值不需要强转
malloc返回的是void类型的指针。因为void是一种通用的指针类型,可以指向任意类型的数据,但
在实际使用时,为了让编译器正确理解指针所指向的数据类型,必须进行强制类型转换。例如:
int *a1 = (int*) malloc(sizeof(int));
而new返回的是所分配对象类型的指针,如new int返回int* ,new MyClass(MyClass是一个自定
义类)返回MyClass* ,不需要进行强制类型转换,这使得代码更加简洁和类型安全。
3.(从参数角度)malloc必须传入具体的字节个数,new传入变量的个数或者变量值
malloc需要传入要分配的内存字节数作为参数,这个字节数通常是通过sizeof操作符来计算得的。
例如,要分配一个能存储 10 个int类型数据的数组内存空间
int *a2 = (int *)malloc(10*sizeof(int));
而new在分配单个对象时,不需要传入字节数,例如new int会自动根据int类型的大小分配足够的内
存空间;在分配数组时,传入数组元素的个数,如new int[10]会分配能存储 10 个int类型数据的连
续内存空间。另外,new还可以在分配对象的同时进行初始化,例如new int(5)会分配一个int类型
的内存空间并初始化为 5。
4.(从函数失败角度)malloc申请失败会返回空,new会抛出异常
当malloc分配内存失败时,它会返回NULL指针。所以在使用malloc分配内存后,通常需要检查返
回值是否为NULL,以确定内存分配是否成功。例如:
int *p = (int *)malloc(sizeof(int));
if (p == NULL) {
// 处理内存分配失败的情况
perror("内存分配失败");
return -1;
}
而new在分配内存失败时(通常是因为系统内存不足),会抛出bad_alloc异常。在 C++ 中,可以
使用try - catch块来捕获这个异常并进行相应的处理。例如:
try {
int *p = new int;
// 正常使用p指向的内存
delete p;
} catch (bad_alloc& e) {
// 处理内存分配失败的异常
cerr << "Memory allocation failed: " << e.what() << endl;
}
5.(从函数体角度)在使用new创建一个类的对象时会先调用malloc 分配内存空间,然后调用构造函
数给成员变量赋值
当使用new创建一个类的对象时,实际上它会进行两步操作。首先,它会像malloc一样在堆上分配
足够的内存空间来存储该对象;然后,它会调用该对象的构造函数来初始化成员变量。这是new和
malloc的一个重要区别,malloc只负责分配内存,而new会同时进行对象的初始化,确保对象在创
建后处于一个合理的初始态。例如:
class MyClass {
public:
int value;
MyClass() { //构造函数
value = 0;
}
};
int main() {
MyClass *p = new MyClass();
// 此时p->value的值为0,因为构造函数将其初始化为0
delete p;
return 0;
}
new和malloc的用法:
new的用法:
1.分配单个基本数据类型变量
语法:指针变量 = new 数据类型
示例:new int在堆上分配了足够存储一个int类型数据的空间,并返回指向该空间的int类型指针。
然后通过解引用指针p可以对这个整数进行赋值操作。最后使用delete操作符释放这块内存,避免
内存泄漏。
int* p = new int;
*p = 10; // 对新分配的整数赋值
delete p; // 释放内存
2.分配单个自定义类型对象
语法:指针变量 = new 类名
示例:new MyClass()会在堆上分配足够存储MyClass对象的空间,然后调用MyClass的构造函数
来初始化这个对象。使用delete时,会调用对象的析构函数来清理资源。
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() {
cout << "构造函数" << endl;
}
~MyClass() {
cout << "析构函数" << endl;
}
};
int main()
{
MyClass* Obj = new MyClass();
// 使用Obj指向的对象
delete Obj;
return 0;
}
3.分配数组
语法:指针变量 = new 数据类型[元素个数]
示例:new int[5]在堆上分配了能够存储 5 个int类型数据的连续空间,返回指向该数组首元素的int*
类型指针。通过循环可以对数组元素进行赋值。使用完数组后,需要使用delete[]来释放整个数组
所占用的内存空间。
int* p = new int[5];
for (int i = 0; i < 5; ++i) {
p[i] = i;
}
delete[] p;
malloc的用法:
1.分配基本数据类型的内存空间
语法:指针变量=(数据类型*)malloc(sizeof(数据类型))
示例:malloc(sizeof(int))用于分配一个大小为int类型字节数的内存空间。因为malloc返回void类型
指针,所以需要将其强制转换为int类型。通过检查p是否为NULL来判断内存分配是否成功。如果
成功,就可以对p进行赋值操作,最后使用free函数释放内存。
int* p = (int*)malloc(sizeof(int));
if (p!= NULL) {
*p = 20;
free(p);
}
2.分配数组内存空间
语法:指针变量=(数据类型*)malloc(元素个数* sizeof(数据类型))
示例:malloc(10 * sizeof(char))分配了一个可以存储 10 个char类型数据的内存空间。同样,需要
将返回的void指针强制转换为char类型。在成功分配内存后,可以对数组元素进行操作,最后使用
free函数释放内存。
char* p1 = (char*)malloc(10* sizeof(char));
if (p1!= NULL) {
p1[0] = 'a';
free(p1);
}
2)malloc分配失败会导致什么问题?
程序运行异常:当malloc分配失败时,它通常返回NULL指针。如果程序没有正确地检查这个返回
值,继续使用这个NULL指针进行读写操作,可能会导致程序崩溃。例如,试图通过NULL指针访问
内存会引发段错误(在大多数操作系统下)。
内存泄漏隐患:在一些复杂的程序中,如果malloc分配失败,但是没有正确地释放之前已经分配的
内存资源,可能会导致内存泄漏。例如,在一个循环中分配内存,当某次分配失败后,没有释放之
前分配成功的内存,这些内存就无法再被程序使用,从而造成内存泄漏。