Linux--内存结构

首先看一串代码

#include <stdio.h>
#include <stdlib.h>

void main(){
        int *p1 = (int *)malloc(4);
        int *p2 = (int *)malloc(4);
        int *p3 = (int *)malloc(4);
        int *p4 = (int *)malloc(4);

        printf("p1 = %p\n",p1);
        printf("p2 = %p\n",p2);
        printf("p3 = %p\n",p3);
        printf("p4 = %p\n",p4);
}


可见每次开辟的空间之间间隔16字节(p2-p1等于16字节),而每次开辟的空间明明只有4字节,多余的12字节从何而来?

原因在于,malloc开辟的内存空间位于堆,堆是由链表维护的,链表的每个结点(结构体)由两部分组成:“数据部分”、“控制部分”。所以对于上面的情况多余的12字节来自于控制部分,并与内存对齐有关。控制部分主要包括上一个结点的地址、下一个结点的地址、当前结点的空间大小等。

在Linux系统中,运行着一个进程,会在"/proc/进程ID"下保存进程运行时所有的信息,进程结束时该文件夹会自动删除。

Linux--内存结构_第1张图片


Linux的内存结构可以分为以下几个部分。

代码段、数据段、BSS段、堆、栈


对于一个空的main函数:

#include <stdio.h>
#include <stdlib.h>

void main(){

}

通过size命令查看可执行文件,可以查看代码段、数据段、BSS段的数据的情况


现在在代码中插入一个局部常量

#include <stdio.h>
#include <stdlib.h>
void main(){
const  int a = 3;
}


没有变化,因为局部常量位于局部栈中。

在代码中插入一个全局常量

#include <stdio.h>
#include <stdlib.h>

const int b = 3;
void main(){
}

代码段增加了4个字节变成1037,所以全局常量位于代码段。


#include <stdio.h>
#include <stdlib.h>

int a=1;
static b=2;
const int c = 3;

void fun(){
}

void main(){
        int a1 = 1;
        static int b1 = 2;
        const int c1 = 3;

        printf("a = %p\n",&a);
        printf("b = %p\n",&b);
        printf("c = %p\n",&c);
        printf("a1 = %p\n",&a1);
        printf("b1 = %p\n",&b1);
        printf("c1 = %p\n",&c1);
        printf("fun = %p\n",fun);
        printf("main = %p\n",main);
}

Linux--内存结构_第2张图片

查看/proc目录下进程中的maps文件

Linux--内存结构_第3张图片


总结:

代码区:存放的CPU的机器指令、全局常量、字符串常量。

数据段:存储初始化的全局变量、静态变量。

BSS段:未初始化的全局变量、静态变量。

堆:动态开辟的内存空间。低地址向高地址扩展

栈:局部变量、局部常量。高地址向低地址扩展


malloc与new的区别:

new的实现是利用malloc,但是在malloc后会初始化空间。

如果是基本数据类型,直接初始化为默认值

如果是UDT,调用对应的构造函数进行初始化


与内存分配有关的函数:

(1)malloc:

(2)void  * calloc(int count , int size):count为元素个数,size为每个元素的大小。分配count*size字节的空间,并初始化。

(3)alloca:原型类似malloc,但在栈中分配空间、

(4)void * realloc(void * ptr , int new_size): 修改已经配置好的内存空间大小,ptr为待修改的空间地址,new_size为新的内存大小。 

若内存减少:则直接返回ptr,内存空间大小变为new_size

若内存增加:若后续空间足够,则返回ptr,内存空间变为new_size。若后续空间不足,则寻找第一个能够满足条件的空间,并将数据拷贝到新内存空间,返回新空间地址。

注:ptr = realloc(ptr , new_size)是不对的,如果分配失败,ptr变为NULL,则原空间不能访问。

你可能感兴趣的:(linux)