动态分配允许我们在程序运行时申请内存的大小。
C++的内存分区
栈区(stack)
有编译器自动分配释放,存放为运行函数而分配的局部变量,函数参数,返回数据,返回地址等。
堆区(heap)
一般有程序员分配释放,若程序员不释放,程序结束时可能会造成内存泄漏。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。
全局区(静态区)
存放全局变量,静态数据,常量。程序结束后由操作系统释放。
文字常量区
常量字符串就在放在这里。程序结束后由操作系统释放。
程序代码区
存放函数体的二进制代码,有操作系统管理。
C++的三种内存分配方式
从静态内存储区域分配
从栈上分配 ( 栈上数据链表原则:先进后出)
从堆上分配,也叫动态分配。(队列上数据链表原则:先进先出)
内存管理
new:
new、delete分配、释放内存空间。C++推荐的分配和释放内存方式。
int* p1 = NULL, * p2 = NULL;
/*
new int(10) 动态分配一个用于存放整型数据的内存空间,并将其值初始化为10。
将该存储空间的地址赋值给p1。
*/
p1 = new int(10);
// 释放p1指向的内存空间
delete p1;
p1 = NULL;
// 动态分配10个连续的整型存储空间,并将其赋值给p2
int n = 10;
p2 = new int[n];
// 访问连续分配的内存空间
p2[1] = 100;
cout << *(p2 + 1) << endl;
// 释放连续内存空间
delete[]p2;
p2 = NULL;
// 输入同学的个数和成绩,求这些同学的平均成绩
cout << "请输入人数:";
cin >> n;
float* a = new float[n];
float sum = 0;
cout << "请输入成绩:" << endl;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
for (int i = 0; i < n; i++)
{
sum += a[i];
}
cout << "平均成绩: " << sum / n << endl;
delete[]a;
malloc:
malloc和free分配释放内存。继承自C语言的内存管理方式。
int* p1 = NULL;
// 分配一个执行存储空间并返回地址
p1 = (int *)malloc(sizeof(int));
*p1 = 100;
cout << *p1 << endl;
// 释放单个内存空
free(p1);
p1 = NULL;
// 分配5个连续的整型内存空间
p1 = (int*)malloc(sizeof(int)*5);
p1[1] = 100;
cout << *(p1 + 1) << endl;
// 释放连续内存空间
free(p1);
new和malloc的区别
使用上的区别:
malloc申请空间需要显式填入申请内存的大小;new无需显式填入,会根据类型分配内存。
返回类型的区别:
new 申请成功时,返回的是对应类型的指针,无需转换;malloc申请成功时,返回void*类型指针,需要强制转换成需要的类型。
分配失败情况时的区别:
new会抛出异常;malloc不会抛出异常,返回NULL。