一.此部分从从一段很简单的程序和一个问题问题开始程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int a1 = 10;
int a2 = 20;
int a3 = 30;
int *p1 = malloc(4);
int *p2 = malloc(4);
int *p3 = malloc(4);
printf("[pid%d]\n",getpid());
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);
while(1);
}
运行结果如下
提两个问题:
1. 为什么a1,a2,a3地址只相隔4个byte,而p1,p2,p3也是申请了4个byte,地址相隔却相隔16个byte?
2. 各种变量(EX:全局,局部,const,static)分别在程序中的那个位置
二.第一个问题主要是延伸出来第一个问题点,malloc怎样分配空间?
先来看一个程序
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
int *p1 = malloc(4);
int *p2 = malloc(4);
int *p3 = malloc(4);
printf("[pid%d]\n",getpid());
*p1 = 1;
*(p1+1) = 2;
*(p1+2) = 3;
*(p1+3) = 4;
*(p1+4) = 5;
*(p1+5) = 6;
*(p1+6) = 7;
*(p1+7) = 8;
printf("%d\n",*p2);
while(1);
}
运行结果如下
怎么会是5呢,其实很简单,看图就一眼明白
但是胡乱更改malloc部分后,再free会如下
也就是说我们已经把malloc的结构已经修改了,造成释放错误
所以总结一个结论:
malloc使用一个数据结构(链表)维护分配空间
链表的构成:分配的空间/上一个空间数据/下一个空间/空间大小等信息.
三.第二个问题其实延伸出来另外一个重要的问题:Linux对内存的结构描述
首先看一个程序
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int add(int a, int b)
{
return a+b;
}
int a1 =1;
staticint a2 = 2;
const inta3 = 3;
int main()
{
int b1 = 4;
static int b2 = 5;
const int b3 = 6;
int *p1 = malloc(4);
printf("pid %d\n",getpid());
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("main:%p\n",main);
printf("add:%p\n",add);
while(1);
}
程序运行如下图
通过程序打印发现pid为4733,所以通过maps看下,通过命令查看
我们发现:
全局变量a1在全局区
static修饰的全局变量a2也在全局区
const修饰的全局变量a3在代码区(竟然在代码区~~~)
局部变量b1在栈区
static修饰的局部变量b2在全局区
const修饰的局部变量b3在栈区
malloc申请的内存毫无疑问在堆区
main和add函数也是毋庸置疑的,在代码区