linux 环境编程学习笔记 第一天 linux 内存管理


 

 

linux 环境编程


一、linux 内存管理 

1.   变量空间

linux 每运行一个程序都会在/proc内生成一个跟自己pid一样的文件夹,你面放着程序有关的信息


ldd ./1

可以看到

linux-vdso.so.1 (0x00007fff47eac000)
libc.so.6 => /lib64/libc.so.6 (0x00007f37c4414000)
/lib64/ld-linux-x86-64.so.2 (0x00007f37c47bc000)

/lib64/ld-linux-x86-64.so.2是一个可执行文件 用来生成 /proc/${pid}内的文件



 

#include<stdio.h>
#include<unistd.h>
#include<malloc.h>
int a1;
static int a2=2;
const int a3=2;
int add(int a,int b)
{
    return a+b;
}
int main()
{

    int b1;
    static int b2=2;
    const int b3=2;
    int *p1;
    int *p2 = (int *)malloc(4);
    printf("a1 %p\n",&a1);
    printf("a2 %p\n",&a2);
    printf("a3 %p\n",&a3);
    printf("b1 %p\n",&b1);
    printf("b2 %p\n",&b2);
    printf("b3 %p\n",&b3);
    printf("p1 %p\n",p1);
    printf("p2 %p\n",p2);
    printf("main %p\n",main);
    printf("f %p\n",add);
    printf("%d\n",getpid());
    while(1);
    return 0;
}


结果

 

a1 0x601060
a2 0x601048
a3 0x400828
b1 0x7fffaa41f41c
b2 0x60104c
b3 0x7fffaa41f418
p1 0x7fffaa41f510
p2 0xddd010
main 0x4005e8
f 0x4005d4
18155


cat /proc/18155/map 结果


00400000-00401000 r-xp 00000000 08:13 1845721                            /codes/gj/1
00600000-00601000 r--p 00000000 08:13 1845721                            /codes/gj/1
00601000-00602000 rw-p 00001000 08:13 1845721                            /codes/gj/1
00ddd000-00dfe000 rw-p 00000000 00:00 0                                  [heap]
7f7916efa000-7f7917099000 r-xp 00000000 08:13 2883641                    /lib64/libc-2.15.so
7f7917099000-7f7917298000 ---p 0019f000 08:13 2883641                    /lib64/libc-2.15.so
7f7917298000-7f791729c000 r--p 0019e000 08:13 2883641                    /lib64/libc-2.15.so
7f791729c000-7f791729e000 rw-p 001a2000 08:13 2883641                    /lib64/libc-2.15.so
7f791729e000-7f79172a2000 rw-p 00000000 00:00 0 
7f79172a2000-7f79172c3000 r-xp 00000000 08:13 2883719                    /lib64/ld-2.15.so
7f7917490000-7f7917493000 rw-p 00000000 00:00 0 
7f79174c1000-7f79174c3000 rw-p 00000000 00:00 0 
7f79174c3000-7f79174c4000 r--p 00021000 08:13 2883719                    /lib64/ld-2.15.so
7f79174c4000-7f79174c5000 rw-p 00022000 08:13 2883719                    /lib64/ld-2.15.so
7f79174c5000-7f79174c6000 rw-p 00000000 00:00 0 
7fffaa400000-7fffaa421000 rw-p 00000000 00:00 0                          [stack]
7fffaa444000-7fffaa445000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]


可以知道  全局的 普通变量、静态变量放在 全局栈中,全局 const变量 放在 代码区 。

                局部普通变量 和const变量都放在局部栈中,static变量放在 全局栈中。malloc申请的空间放在 堆中。

                main函数 和 自己写的函数 都是放在 代码区的。


2.malloc 申请的内存

 

#include<stdio.h>
#include<unistd.h>
#include <malloc.h>

int main(int argc, const char *argv[])
{
    int a1 = 10;
    int a2 = 10;
    int a3 = 10;

    int *p1 = (int*)malloc(4);
    int *p2 = (int*)malloc(4);
    int *p3 = (int*)malloc(4);

    printf("a1 %p\n",&a1);
    printf("a2 %p\n",&a2);
    printf("a3 %p\n",&a3);

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


    printf("%d\n",getpid());
    while(1);
    return 0;
}


结果:
a1 0x7fff4445f7a4
a2 0x7fff4445f7a0
a3 0x7fff4445f79c
p1 0x1dcb010
p2 0x1dcb030
p3 0x1dcb050
18323

 

 

可以知道:
1. 普通变量是在栈中的,它的地址是 越早分配的地址越大,malloc 创建的内存是在堆中的地址是按顺序分配下来的
2. malloc申请的变量不是申请4个字节就只占用4个直接,具体见后面。


3.malloc申请的内存结构

 

#include<stdio.h>
#include<malloc.h>

int main(int argc, const char *argv[])
{
    int *p1 = malloc(4);
    int *p2 = malloc(4);
    int *p3 = malloc(4);
    *p1 = 1;
    *(p1+1) = 2;
    *(p1+2) = 3;
    *(p1+3) = 4;
    *(p1+4) = 5;
    *(p1+5) = 6;
    *(p1+6) = 7;
    *(p1+7) = 8;
    *(p1+8) = 10;
    *(p1+9) = 11;

    //free(p1);
    printf("%d\n",*p2);
    return 0;
}
结果:
10

 



虽然看起来没有什么错,但如果 free(p1)就会出现严重的错误。
原因   堆是由链表管理的,malloc 生成的空间  先本身的数据,再是前一个元素的地址,再是后一个元素的地址,再后一个是本身数据的长度。所以改变 p1+2 p1+3 的值会使 free 出错。


 

4.new delete跟 malloc free有什么区别

new就是靠malloc的 delete 就是靠free的,
只是new 在生成是会初始化,delete在删除是会先清0。


其他知识点:

c语言是弱类型语言,c++是强类型语言
int *p = malloc(4);
在c是对的,在c++是错的,c++一定要(int*)malloc(4);
gcc xxx.cpp 是按照c++ 编译的
gcc xxx.c     才会按照c编译

 

  • yuxiaoqiang

    评论: 313

    2021-04-14 00:57:48          回复

  • nik

    评论: good

    2019-03-28 16:18:45          回复

  • erick

    评论: 不错 哦

    2019-01-21 16:31:02          回复

  • varden

    评论: hi

    2018-11-20 09:33:04          回复

  • Test

    评论: Test

    2018-03-15 23:22:47          回复

  • iyangfeixiang

    评论: 看看怎么样

    2017-10-25 16:23:23          回复

  • xxoo

    评论: 21

    2016-12-28 14:52:48          回复

  • linsc

    @shadow: 楼主,我用你开源的代码部署后,怎么什么都不能干。。。比如添加文章什么的

    评论: 好像

    2016-12-16 23:50:19          回复

  • ganxie_blog

    评论: 测试,感谢开源

    2015-12-24 23:15:04          回复

  • zhangqin

    评论: test again

    2015-07-06 15:57:02          回复

  • zhangqin

    评论: test

    2015-07-06 15:56:55          回复

  • billvsme

    评论: 加我 qq 994171686

    2015-05-15 00:16:29          回复

  • shadow

    评论: 楼主,我用你开源的代码部署后,怎么什么都不能干。。。比如添加文章什么的

    2015-05-14 20:55:06          回复