一、new和malloc的基本概念
new
和malloc
都是用于动态分配内存的函数。dynamic memory allocation是指在程序运行时动态分配内存,也称堆分配(heap allocation),与静态内存分配(即编译时内存分配)相对应。C引入了new
和delete
来代替C语言中常用的malloc
和free
。
malloc
(memory allocation)函数定义在stdlib.h
头文件中。malloc
函数申请一块指定大小的内存块,并返回指向该内存块的指针。内存中的数据是未初始化的,需要使用memset
函数来清零。
new
和delete
是C的关键字,是一对运算符。使用new
运算符可以动态分配内存,并返回指向新内存的指针,而使用delete
则可以将内存释放。
// malloc的用法示例
#include<stdlib.h>
int main(){
int *p = (int*)malloc(sizeof(int));
*p = 10;
free(p);
return 0;
}
// new的用法示例
#include <iostream>
int main(){
int *p = new int;
*p = 10;
delete p;
return 0;
}
二、new与malloc的区别
1.返回值类型不同
malloc
返回void
类型指针,在C++语言中需要进行强制类型转换才能赋值给指定类型的指针。new
则返回指定类型的指针,不需要进行强制类型转换。
#include<iostream>
#include <stdlib.h>
int main(){
int *p = (int*)malloc(sizeof(int));
int *q = new int;
std::cout << typeid(p).name() << std::endl;
std::cout << typeid(q).name() << std::endl;
free(p);
delete q;
return 0;
}
// 运行结果:Pv(void指针类型), Pi(int指针类型)
2.运算符重载
new
和delete
是C++的关键字,是一对运算符,支持重载。使用new
可以自动调用构造函数,使用delete
可以自动调用析构函数。
#include<iostream>
class A{
public:
A(){std::cout << "A constructor" << std::endl;}
~A(){std::cout << "A destructor" << std::endl;}
};
int main(){
A *a1 = (A*)malloc(sizeof(A));
A *a2 = new A();
free(a1);
delete a2;
return 0;
}
// 运行结果只有new能调用构造函数和析构函数
3.内存越界检查
new
进行内存分配时,会进行越界检查。
#include<iostream>
#define LEN 10
int main(){
int *p1 = (int*)malloc(sizeof(int) * LEN);
int *p2 = new int[LEN];
for(int i = 0; i < LEN+5; ++i){
std::cout << p1[i] << " "; // 越界访问p1,并不会抛出异常
}
std::cout << std::endl;
for(int i = 0; i < LEN+5; ++i){
std::cout << p1[i] << " "; // 越界访问p2,会抛出异常
}
free(p1);
delete[] p2;
return 0;
}
4.分配对象空间不同
new
可以同时分配对象和空间,而malloc
只能分配空间。
#include<iostream>
#include <string.h>
class A{
public:
int x;
char* str;
};
int main(){
A *a1 = (A*)malloc(sizeof(A)); // 只分配空间,需要手动初始化对象
a1->x = 1;
a1->str = (char*)malloc(sizeof(char) * 10);
strcpy(a1->str, "hello");
std::cout << "x = " << a1->x << ", str = " << a1->str << std::endl;
free(a1->str);
free(a1);
A *a2 = new A(); // 分配空间并初始化对象
a2->x = 2;
a2->str = (char*)malloc(sizeof(char) * 10);
strcpy(a2->str, "world");
std::cout << "x = " << a2->x << ", str = " << a2->str << std::endl;
free(a2->str);
delete a2;
return 0;
}
三、小结
new
和malloc
都是用于动态分配内存的函数。new
和delete
是C++的关键字,支持运算符重载和对析构函数的调用,可以自动调用构造函数和析构函数。new
进行内存分配时会进行内存越界检查,malloc
不会。new
可以同时分配对象和空间,而malloc
只能分配空间。选择使用哪个函数,需要结合具体的情况来考虑。