程序的内存分段

程序的内存分段

当执行程序的运行命令后,操作系统会给程序分配它所需要的内存,并划分成以下内存段供程序使用:

text 代码段:

​ C代码被翻译成二进制指令后存储在可执行文件中,当可执行文件被操作系统执行时,它会把里面的二进制指令(编译后的代码)加载到这个内存段,它里面的内容决定了程序如何执行,为了避免程序被破坏、修改,所以它的权限是只读

​ 该内存段分为两个部分(权限一样):

​ r-x:二进制指令 r–:常量数据

​ r-xp r–p

注意:该内存段的内容如果被强制修改会产生段错误(非法使用内存)。

data 数据段:

​ 存储的是初始化过的全局变量

​ 存储在内存段的变量,被const修饰后,就会改存储到text内存段,变成真正的常量。

bss 静态数据段:

​ 存储的是未初始化的全局变量

​ 操作系统把程序被加载到内存后,会把该内存段进行初始化,也就是所有字节赋值为零,所以其默认值不是随机,而是零

heap 堆:

​ 该内存段由程序员手动调用内存管理函数(malloc/free),进行分配、释放,它的分配释放受程序员的控制,适合存储一些需要长期使用的数据。

​ 它的大小不受限制,理论上能达到物理的上限,所以适合存储大量的数据。

​ 该内存段无法取名字,也就是无法与标识符建立联系,必须与指针配合使用。(比如malloc的返回值就是内存块首地址 void*)

stack 栈:

​ 存储的是局部变量、块变量(例如数组)

​ 该内存段会随着程序的执行自动的分配(定义局部变量、块变量)、释放(函数执行完毕自动释放局部变量、块变量),虽然使用比较方便,但它的释放不受程序控制,长期使用的数据不能存储在栈内存中。

​ 该内存的大小有限,在终端执行: ulimit -s 可以查看当前系统栈内存的使用上限,我们使用虚拟机ubuntu的栈内存使用上限是8192kb也就是8M,一旦超过这个限制就会产生段错误。可以使用ulimit -s 命令设置栈内存的使用上限(下次开机不想回到默认值,需修改配置文件)。
在这里插入图片描述
修改:
/etc/security/limits.conf

etc/rc.local

静态内存:

​ 当程序完成编译 text、data、bss 三个内存段的大小就确定,在程序运行期间大小不会有任何变化,可以使用size命令查看程序的这三个内存段的大小。

#include
int num;
int main(int argc,const char* argv[])
{
	printf("hello world!");
	return 0;
}

#include
int num=1;
int main(int argc,const char* argv[])
{
	printf("hello world!");
	return 0;
}

#include
const int num=1;
int main(int argc,const char* argv[])
{
	printf("hello world!");
	return 0;
}

程序的内存分段_第1张图片
初始化后:data+4,bss-4
const+初始化:data-4,text+4

动态内存:

​ heap、stack两个内存段,会随着程序的执行动态变化。

​ 当程序运行时,/proc/程序编号/maps 文件里记录程序执行过程中内存的使用情况,程序运行结束这个文件就消失了。

ps aux命令查看所有进程的编号,getpid函数可以获取当前进程的编号

你可能感兴趣的:(C语言,c语言)