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编译
@shadow: 楼主,我用你开源的代码部署后,怎么什么都不能干。。。比如添加文章什么的