栈中存储的是局部变量,函数参数,返回值等
堆主要用于动态内存分配
数据段用以存储全局数据和静态数据
代码段存储可执行代码和常量
在C语言中,我们使用 malloc、calloc、realloc、free来进行动态内存管理。而在C++中这些方法仍可以继续使用,但是在面对自定义类型对象的创建时显得无能为力了,因此C++引入了new和delete操作符
- int main()
- {
- int* a = new int;//创建整型变量a
- delete a;
- int* b = new int(5);//创建整型变量b,并初始化为5
- delete b;
- int* arr = new int[10] {0,1,2};//创建整型数组,并将其初始化
- delete[] arr;
- return 0;
- }
在内置类型中,C语言的malloc和free与C++中的new和delete使用起来差别并不大。但是在自定义类型中,new和delete就很重要了。原因就在于,在自定义类型中,new和delete可以分别调用构造函数和析构函数来对对象完成初始化和资源清理。
- int main()
- {
- // new / delete 和 malloc / free最大区别是 new / delete对于【自定义类型】除了开空间还会调用构造函数和析构函数
- A* p1 = (A*)malloc(sizeof(A));
- A* p2 = new A(1);
- free(p1);
- delete p2;
- // 内置类型是几乎是一样的
- int* p3 = (int*)malloc(sizeof(int)); // C
- int* p4 = new int;
- free(p3);
- delete p4;
- A* p5 = (A*)malloc(sizeof(A) * 10);
- A* p6 = new A[10];
- free(p5);
- delete[] p6;
-
- return 0;
- }
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
具体的源码如下
- void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
- {
- // try to allocate size bytes
- void *p;
- while ((p = malloc(size)) == 0)
- if (_callnewh(size) == 0)
- {
- // report no memory
- // 如果申请内存失败了,这里会抛出bad_alloc 类型异常
- static const std::bad_alloc nomem;
- _RAISE(nomem);
- }
- return (p);
- }
- /*
- operator delete: 该函数最终是通过free来释放空间的
- */
- void operator delete(void *pUserData)
- {
- _CrtMemBlockHeader * pHead;
- RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
- if (pUserData == NULL)
- return;
- _mlock(_HEAP_LOCK); /* block other threads */
- __TRY
- /* get a pointer to memory block header */
- pHead = pHdr(pUserData);
- /* verify block type */
- _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
- _free_dbg( pUserData, pHead->nBlockUse );
- __FINALLY
- _munlock(_HEAP_LOCK); /* release other threads */
- __END_TRY_FINALLY
- return;
- }
- /*
- free的实现
- */
- #define free(p) _free_dbg(p, _NORMAL_BLOCK)
可以了解到operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。