从零开始学c++——C++动态内存管理
Posted sjp11
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从零开始学c++——C++动态内存管理相关的知识,希望对你有一定的参考价值。
C++动态内存管理
1.C/C++内存分布
接下来我们来看一下例子:
int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
static int staticVar = 1;
int localVar = 1;
int num1[10] = {1, 2, 3, 4};
char char2[] = "abcd";
char* pChar3 = "abcd";
int* ptr1 = (int*)malloc(sizeof (int)*4);
int* ptr2 = (int*)calloc(4, sizeof(int));
int* ptr3 = (int*)realloc(ptr2, sizeof(int)*4);
free (ptr1);
free (ptr3);
}
- 选择题:
选项: A.栈 B.堆 C.数据段 D.代码段
globalVar在哪里?____ staticGlobalVar在哪里?____
staticVar在哪里?____ localVar在哪里?____
num1 在哪里?____
char2在哪里?____ *char2在哪里?___
pChar3在哪里?____ *pChar3在哪里?____
ptr1在哪里?____ *ptr1在哪里?____
答案:
解析:因为globalVar是全局变量,staticGlobalVar和staticVar是静态变量,所以它们存储在数据段中,localVar是main函数中的局部变量,num1 是数组名,表示的是数组首元素的地址,为指针变量,也为局部变量,所以它们存储在栈中,
char char2[] = "abcd"表示的意思是将字符串“abcd”拷贝一份存储在char2[]的数组中,所以char2和*char2都表示的是局部变量,都存储在栈中,
char* pChar3 = "abcd"表示的是将“abcd”的地址储存在pChar3中,所以pChar3是局部变量,而*pChar3是常量字符串,储存在代码段,
int* ptr1 = (int*)malloc(sizeof (int)*4);表示的是动态开辟一块空间,然后将这块空间的地址存储在ptr1,所以ptr1为局部变量,*ptr1指向动态内存。
2.c++中的动态内存管理
与之前学过的c语言知道,要想申请一块动态内存,我们要使用malloc去向系统申请一块空间,系统就会将这块空间的使用权给你当这块空间不用时,我们在把这块间free掉,也就是这块空间的使用权还给系统。
问题:malloc/calloc/realloc的区别?
malloc会在堆上申请一块动态空间,但这块空间没有初始化,而calloc也会去堆上申请一块空间,但会把这块空间初始化为0,realloc则针对已有的空间进行扩容(有原地扩容和异地扩容)
而c++中则一般会用new/delete去申请动态空间。
int main()
{
//申请10个int类型的空间
int* p1 = (int*)malloc(sizeof(int) * 10);
int* p2 = new int[10];
free(p1);
delete[]p2;
//申请一个int类型的空间
int* p3 = (int*)malloc(sizeof(int));
int* p4 = new int;
free(p3);
delete p4;
return 0;
}
注意:new/delete new[]/delete[]一定要匹配,否则可能会出错。
我们可以看到new类型比malloc操作起来更方便一些,看起来清楚明了,但是难道仅仅只有这些吗,答案是否定的。
由上图可以见,用new去申请自定义类型的空间,它会去自动调用构造函数初始化,用delete去释放空间,则会去调用析构函数。
如果申请3个ListNode的空间,则会调用3次的构造函数,delete时也会去调用3次析构函数。
3.operator new和operator delete
首先我们得知道new的执行过程它会去调用operator new去申请空间和调用构造函数初始化,delete的执行过程会去调用operator delete去释放空间和析构函数完成对象的资源清理工作。
而operator new的底层相当于malloc开空间和抛异常,operator delete的底层相当于free释放空间和抛异常。
什么是抛异常?
抛异常的方法来实现当次执行的程序中断,而不是整个程序全部终止,而断言则会使整个程序终止。
4.什么是内存泄露
申请的空间使用完后没有及时释放,而是指向的那块空间的指针给先销毁掉,导致这块空间没有还给系统,这块空间我们却找不到它,系统不能去重新分配这块空间,但是那块依然存在那里,最终造成内存的浪费。
内存泄露的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。所以要特别注意及时释放内存。
5.malloc/free和new/delete的区别
malloc/free,new/delete的共同点都是在堆上申请空间,需要自己释放。
而它们的不同的有:
1.new/delete定义自定义类型会自动调用构造函数和析构函数,而malloc/free不会。
2.new申请空间失败直接抛异常,malloc/f出错返回空指针。
3.new/delete是操作符,malloc/free是函数。
4.malloc申请空间时需要计算空间大小,new只需要在加上空间的类型即可。
5.malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型。
以上是关于从零开始学c++——C++动态内存管理的主要内容,如果未能解决你的问题,请参考以下文章