C++的内存分配方式
之前有说过C++的内存分为5部分,即栈、堆、全局/静态存储区、自由存储区以及常量存储区。
栈:栈由编译器自动分配与释放,它用来存储函数的参数值以及局部变量。
堆:堆由应用程序分配与释放,应用程序使用malloc在堆上获取内存,使用free释放内存。如果应用程序获取内存后没有释放,就会造成内存泄漏,在应用程序终止时泄漏的内存才会被操作系统回收。
自由存储区:自由存储区是C++中基于new和delete的抽象概念。当应用程序使用new分配内存时,就说该内存是自由存储区。C++编译器基本上使用malloc来实现operator new,所以使用new分配的内存既可以说是在堆上也可以说是在自由存储区。但是operator new允许被重载,应用程序可以将operator new实现为在其他内存区域(比如静态存储区)上获取内存,这时自由存储区和堆就不是一个概念。
全局/静态存储区:全局和静态变量是存放在一块的,在C中,初始化的全局/静态变量存放在进程的data区内,未初始化的全局/静态变量存放在bss区。在C++中不做这样的区分。
常量存储区:这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。
静态链接库和动态链接库(unix)
在UNIX系统中,静态链接库以一种称为存档(archive)的文件格式存放在磁盘上。存档文件是一组连接起来的可重定位目标文件的集合,可重定位目标文件可由相关函数编译而成,有一个头部用来描述每个成员文件的大小和位置。存档文件名由后缀.a标识。静态链接库的链接是在编译时期完成的,链接时链接器只拷贝被程序引用的目标文件。
静态链接库存在2个缺点:
1)需要定期维护和更新,程序使用最新版本的库时需要显式地与其链接。
2)对于那些常用的库函数,在运行时,都会被拷贝到每个运行进程的文本段中,对内存造成了极大地浪费。
为此提出动态链接库的概念,它是一个目标文件,在运行时可以和内存中的进程链接,该过程由动态连接器完成,在unix中其后缀名为.so。所有引用动态链接库的进程共享库中的代码和数据,而被引用静态链接库会被拷贝到每个进程的可执行文件中。同时,一个动态链接库的文本段的一个副本可以被不同正在运行的进程共享。