operator new、malloc、HeapAlloc分配内存有何不同?

本文详细介绍了C++中三种不同的内存区域:静态存储区、栈和堆,并解释了operator new、alloc及HeapAlloc等函数如何在堆中分配内存。此外还讨论了new与delete、malloc与free之间的区别和正确用法。

operator new、alloc、HeapAlloc都是在堆(heap)中分配内存,跟栈(stack)没有关系,new 和 alloc分配内存的方式应该是一样的,所以用alloc分配的空间可以用delete释放,而用new分配的空间也可以用free释放,不同的是,用delete在释放内存前还会调用析构函数,所以用new创建的最好还是用delete释放。

另外,HeapAlloc和HeapFree必须搭配使用,因为HeapAlloc分配的内存空间,delete和free不能正确释放,new、malloc分配的空间也不能被HeapFree正确处理 . 

 

 

C++将内存划分为三个内存区:


1:静态存储区,主要存放全局变量和用用static定义的变量,这部分内存在程序编译时刻已经
分配好,并且在整个程序运行期间都存在。


2:在栈(stack)创建内存,一般用于存放局部变量或对象, 这部分主要是程序运行期间,定义的临时对象,调用函数时在函数内部定义的变量,比如
fun()
{
int i;// 栈上创建

}


当结束临时对象的生命期时,或者调用函数结束时,在栈上创建的对象,会被系统自动回收
这就是为什么我们
定义 int i;
或者 class A;A a;
不会产生内存泄露的原因,因为系统自动回收了这部分内存。
在栈上创建对象的好处是:栈内存分配运算内置于处理器的指令集
中,效率很高,但是分配的内存容量有限。


3:在堆(heap)创建对象,主要是用户通过调用new/delete或者malloc/free来创建销毁对象

好处是:用户可以根据自己要求创建内存大小,非常灵活。
缺点是:这部分内存必须有用户自己来销毁,也就是这部分最容易造成内存泄露。执行速度相对于在栈上的速度要慢。



例子说明
int iTemp(10);// 静态存储区
static char chTemp[] = "test";//静态存储区
int fun (int i)
{
int j = i;//j,i都是在栈上创建
cout << j;
ruturn j*2;// 返回值是在栈上创建
}
int fun1()// 以下是错误定义,仅为说明问题
{
int *p = new int(10);//堆上创建
int *p1 = (int*)malloc (sizeof(int));//堆上创建
return (*p);
}
int main()
{
int itemp;//栈上创建
int *p = new int(10);//堆上创建
int *p1 = (int*)malloc (sizeof(int));//堆上创建
}


还有把new 和delete 与malloc 和free 混在一起用也是个坏想法。对一个用new
获取来的指针调用free,或者对一个用malloc 获取来的指针调用delete,其后
果是不可预测的


原因是:new是C++的操作符,用new可以创建class对象,可以申请适合class对象大小的内存
并可以执行class的构造函数,创建类对象,用delete时,不但可以销毁new的内存,并且还可以
对class对象,调用析购函数,释放class申请的资源。如果用是class对象,用new申请,用free
释放,会有什么发生那?free只是释放内存空间,并没有析购class对象,也就是说对象并没有
被销毁,造成内存泄露。


如果用malloc申请,用delete释放那,理论上来说是没有问题的,但是我想谁也不乐意这么做。

还有使用new和malloc,一定要和delete和free成对出现、要注意防止内存泄露。
当然如果你用STL的auto_ptr可以不用显示delete,由系统帮你delete。

 

 

### C++ 中 `new` 和 `malloc` 的底层实现差异及原理 #### 1. 内存分配的基本流程 在 C++ 中,`new` 和 `malloc` 都用于动态内存分配,但它们的底层实现和使用场景存在显著差异。`malloc` 是 C 语言提供的函数,而 `new` 是 C++ 的运算符,专门设计用于对象的动态创建。 - `malloc` 只负责分配原始内存块,不会调用构造函数来初始化对象[^2]。 - `new` 不仅分配内存,还会调用构造函数对对象进行初始化[^3]。 #### 2. 底层实现机制 `new` 和 `malloc` 的底层实现可以分解为以下几个关键点: ##### (1) 内存分配阶段 `new` 的底层实现通常会调用 `operator new` 函数来分配内存,而 `operator new` 通常基于 `malloc` 实现。例如,以下是一个简单的 `operator new` 实现示例: ```cpp void* operator new(std::size_t size) { if (void* mem = malloc(size)) { return mem; } else { throw std::bad_alloc(); } } ``` 如果 `malloc` 分配内存失败,`operator new` 会抛出 `std::bad_alloc` 异常,而不是返回 `NULL` 指针[^3]。 ##### (2) 对象初始化阶段 对于自定义类型(如类对象),`new` 在分配内存后会调用类型的构造函数以初始化对象。例如: ```cpp class MyClass { public: MyClass() { std::cout << "Constructor called" << std::endl; } ~MyClass() { std::cout << "Destructor called" << std::endl; } }; int main() { MyClass* obj = new MyClass(); // 调用构造函数 delete obj; // 调用析构函数 return 0; } ``` 上述代码中,`new MyClass()` 会先通过 `operator new` 分配内存,然后调用 `MyClass` 的构造函数完成对象初始化。 相比之下,`malloc` 仅分配原始内存,不会执行任构造或初始化操作。开发者需要手动管理内存中的数据,这可能导致错误或未定义行为。 ##### (3) 内存释放阶段 当使用 `delete` 释放动态分配的对象时,C++ 会先调用对象的析构函数,然后再通过 `operator delete` 释放内存。`operator delete` 通常基于 `free` 实现,例如: ```cpp void operator delete(void* mem) noexcept { free(mem); } ``` #### 3. 主要区别总结 以下是 `new` 和 `malloc` 的主要区别及其底层实现差异: | 特性 | `malloc` | `new` | |-----------------------|------------------------------------------------|-----------------------------------------------| | **功能** | 仅分配原始内存 | 分配内存并初始化对象 | | **返回类型** | `void*` | 具体类型的指针 | | **异常处理** | 分配失败返回 `NULL` | 分配失败抛出 `std::bad_alloc` 异常 | | **构造与析构** | 不调用构造函数或析构函数 | 自动调用构造函数和析构函数 | | **底层实现** | 直接由标准库提供 | 基于 `malloc` 实现 `operator new` | #### 4. 使用场景分析 - 如果只需要分配原始内存且不需要对象初始化,则可以使用 `malloc` 或 `calloc`。 - 如果需要动态创建对象并确保其正确初始化,则应使用 `new`,因为它更符合 C++ 的面向对象编程原则[^3]。 #### 示例代码对比 以下代码展示了 `malloc` 和 `new` 的使用差异: ```cpp #include <iostream> #include <cstdlib> struct Point { int x, y; Point(int x, int y) : x(x), y(y) {} void display() const { std::cout << "Point(" << x << ", " << y << ")\n"; } }; int main() { // 使用 malloc Point* p1 = (Point*)malloc(sizeof(Point)); if (p1) { p1->x = 10; p1->y = 20; p1->display(); free(p1); } // 使用 new Point* p2 = new Point(10, 20); // 自动调用构造函数 p2->display(); delete p2; return 0; } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值