热身试题
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";
const 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在哪里?C (全局数据统一在数据段)
staticGlobalVar在哪里?C(全局静态也在数据段)
staticVar在哪里?C(局部静态依旧在数据段)
localVar在哪里?A(普通局部变量在栈区)
num1 在哪里?C(局部数组也在栈区)
char2在哪里?A(局部变量在栈区)
*char2在哪里?A(数组名是首元素的地址,解引用得到第一个元素,放在栈区)
pChar3在哪里?A(局部变量在栈区)
*pChar3在哪里?D(第一个字符在常量区)
ptr1在哪里?A (局部变量指针在栈区)
*ptr1在哪里?B(动态开辟的在堆区)
栈区:又叫堆栈,存放非静态局部变量/函数参数/返回值等等,并且栈是向下增长的,申请空间有限(大致只有N兆),所以这也是为什么递归不宜太深,栈溢出的原因 。
堆区:一般由程序员分配释放, 若程序员不释放,会造成内存泄漏,并且堆是向上增长的
内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
数据段(静态区):存放全局变量、静态数据。程序结束后由系统释放。
代码段(常量区):存放函数体(类成员函数和全局函数)的二进制代码与只读常量。
C++中的内存管理
new与delete对于内置类型的操作
#include <iostream>
using namespace std;
int main()
{
//开辟一个整型大小的空间
int* p1 = new int;
//开辟一个大小为10个整型的空间
int* p2 = new int[1];
//释放空间,功能和free相似
delete p1;
delete[] p2;
//申请对象并初始化
int* p3 = new int(0);
//申请10个整型大小的空间,全部初始化为0
int* p4 = new int [10] {0};
//申请10个整型大小的空间,前5个值初始化,剩余的数默认为0
int* p5 = new int[10] {1, 2, 3, 4, 5, };
delete p3;
delete[] p4;
delete[] p5;
return 0;
}
new与delete对于自定义类型的操作
new会自动调用构造函数
delete会自动调用析构函数
new和delete不同的是:
new/delete申请和释放的是单个元素空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc则是返回NULL
free和malloc不会调用析构函数和构造函数,所以new和delete主要使用在自定义类型。
malloc/free和new/delete的区别
1.malloc和free是函数,new和delete是操作符。
2. malloc申请的空间不会初始化,new可以初始化。
3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可如果是多个对象,几中指定对象个数即可。
4. malloc的返回值为void*,在使用时必须强转,new不需要,因为new后跟的是空间的类型。
5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常。
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new5在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理释放。
希望这篇博客对你有所帮助!!!