内存管理
C/C++内存管理
- 临时变量放栈
- 动态开辟放堆
- 静态变量,全局变量放数据段(静态区)(全局变量所有文件中可见,静态变量只在当前文件可见)
- 常量字符串在代码段(常量区)
内存从上到下 内存空间(用户代码不能读写) 栈(向下增长) 内存映射区(文件映射,内存库,匿名映射) 堆(向上增长) 数据段(全局数据 静态数据) 代码段(可执行代码/只读常量)
操作系统内存管理(感兴趣看《深入理解计算机》)
- 分段:不同用途数据放到不同的区域,就像我们现实中也会对河北划分区域一样
- 分页
一个你写出来的程序在linux是如何被编译运行起来的
- 编写的代码时存在文件系统上的
- 编译器去读这个程序,通过编译链接生成二进制可执行程序a.out
- ./a.out在一个终端下去运行程序,运行程序a.out相当于创建了一个子程序,exec对创建的子程序进行替换,替换成a.out
C/C++中动态内存管理方式
malloc/calloc/realloc的区别?
- malloc开辟空间
- calloc开辟空间+初始化
- realloc扩容
int main()
{
//C语言
int *p1=(int*)malloc(sizeof(int));
int *p3=(int*)malloc(sizeof(int)*10);
free(p1);
free(p3);
//C++操作符
int *p2=new int;
int *p5=new int(10);//申请一块空间,初始化为10
int *p4=new int[10];//申请十块空间
delete p2;
delete[] p4;
return 0;
}
- 既然有了malloc和free,new和delete存在的意义是什么
-
对于申请上面内置类型,效果一样
-
对于申请自定义类型,效果不一样,malloc只是申请空间,new申请空间+构造函数初始化
free只是释放空间,delete析构函数+释放空间
-
C++中建议使用new和delete
operator new与operator delete函数
- operator new 和 malloc的区别是什么?
- malloc申请空间失败返回0,operator new 申请空间失败抛异常(面向对象处理错误的方式)
- 使用方式一样
- operator new==>malloc+失败抛异常实现
- new=operator new+构造函数
- new比起malloc不一样的地方:1. 调用构造函数初始化 2. 失败抛异常
- operator new是因为new才产生的
- delete比起free不一样的地方:1. 调用析构函数管理
- operator delete和free没区别,因为如果释放空间失败直接终止程序,opreator delete是为了和operator配对才出现的
#include<iostream>
#include<stdlib.h>
using namespace std;
class A
{
public:
A()
{
cout<<"A()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
private:
int _a;
};
int main()
{
A* p1=(A*)malloc(sizeof(A));
A* p2=new A;
A* p3=(A*)operator new(sizeof(A));
operator delete(p3);
delete p2;
free(p1);
return 0;
}
定位new
#include<iostream>
using namespace std;
class A
{
public:
A(int a=10)
:_a(a)
{
cout<<"A()"<<endl;
}
~A()
{
cout<<"~A()"<<endl;
}
private:
int _a;
};
int main()
{
A*p=new A;
delete p;
//想模拟上面的行为
//显示调用了A的构造函数和析构函数
A* p2=(A*)operator new(sizeof(A)) ;
//对已经存在的一块空间调用构造函数初始化
//定位new /replacement new
new(p2)A(10);//new(空间指针)类型(参数)
p2->~A() ;
operator delete(p2);
return 0;
}
常见面试题
- malloc和new的区别
- new会调用构造函数,失败抛异常,malloc失败返回0 使用效果
- malloc是一个函数,new是操作符 概念性质
- malloc用法:参数传字节数,返回值是void*,new后面跟申请对象的类型,返回值是类型的指针 使用方法
- 内存泄漏(c++独有问题,java没有,因为有垃圾回收器,new之后不用释放)
int main()
{
char*p=new char[1024*1024*1024];
//内存泄漏:P指向的空间不需要了,忘记或其他原因释放P指向的空间,就内存泄漏
//内存泄漏危害:长期运行的程序,出现内存泄漏危害很大,或者设备的内存本身很小危害很大
return 0;
}
- 事前预防型:使用智能指针
- 事后差错行:如检测泄露工具
- 如何申请4g空间
int main()
{
size_t n=2;
try
{
void*p=new char[n*1024*1024*1024];
}
//改64位
return 0;
}