代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布

时间:2022-08-04 16:15:31

学习结构体之后,就想着来看看栈上多个变量的地址的分配情况,是不是也有某种规则一个接一个挨着。不想发现连续的两个变量的地址并不连续,可以说分得很开,而且从高地址到低地址分配。
虽然并不知道系统(还是编译器? 谁告诉我下)为什么这么做,但索性写了个程序也看看其它区域是怎么分配地址的。
小代码如下,如果有错误,请留言,我会从心底里感谢你的。

#include <stdio.h>
#include <string.h>
#include <cstdlib>

//打印整形数组
void printfarr(unsigned long *arr, size_t size){
for (size_t i = 0; i < size; i++)
{
printf("%x ", arr[i]);
}
printf("\n");
}

//根据传入的数组arr,比较大小,在out上对应标上其大小的顺序值
//总觉得这个算顺序的办法好笨,谁有更好的麻烦贡献出来
void sx(unsigned long* arr, unsigned long *out, size_t size){
memset(out, -1, size*sizeof(unsigned long));

for (size_t i = 0; i < size; i++)
{
int min;
for (size_t j = 0; j < size; j++)
{
if (out[j]==-1)
{
out[j] = i + 1;
min = j;
break;
}
}

for (size_t k = min + 1; k < size; k++)
{
if((out[k]==-1) && (arr[k] < arr[min])){
out[min] = -1;
out[k] = i + 1;
min = k;
}
}
}
}

//全局区(静态区)(static)
int static1 = 1;
int static2 = 1;
int static3 = 1;

//文字常量区
const char *str1 = "abc";
const char *str2 = "abc";
const char *str3 = "abcd";
const char *str4 = "abcde";

//程序代码区
void testadd1(){ int a; }
void testadd2(){ int b; }
void testadd(){
//栈区
int stack1 = 1;
int stack2 = 1;
int stack3 = 1;
//堆区地址
int *heap1 = (int *)malloc(sizeof(int));
int *heap2 = (int *)malloc(sizeof(int));
int *heap3 = (int *)malloc(sizeof(int));

printf("程序代码区的地址\n");
printf("testadd1=%x\n", testadd1);
printf("testadd2=%x\n", testadd2);
printf("testadd=%x\n", testadd);

printf("文字常量区 常量的地址\n");
printf("str1=%x\n", str1);
printf("str2=%x\n", str2);
printf("str3=%x\n", str3);
printf("str4=%x\n", str4);

printf("全局区(静态区)(static)变量的地址\n");
printf("&static1=%x\n", &static1);
printf("&static2=%x\n", &static2);
printf("&static3=%x\n", &static3);

printf("栈区 变量的地址\n");
printf("&stack1=%x\n", &stack1);
printf("&stack2=%x\n", &stack2);
printf("&stack3=%x\n", &stack3);

printf("堆区 空间的地址\n");
printf("heap1=%x\n", heap1);
printf("heap2=%x\n", heap2);
printf("heap3=%x\n", heap3);

unsigned long a[5] = { (unsigned long)testadd1, (unsigned long)str1, (unsigned long)&static1, (unsigned long)&stack1, (unsigned long)heap1 };
unsigned long a1[5];
sx(a, a1, 5);
printfarr(a, 5);
printfarr(a1, 5);
printf("\n");
}

int main()
{
testadd();
//testsx();
return 0;
}

多次运行结果
代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布
代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布
代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布
代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布
代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布

经过多次测试发现:
1,从低到高分配地址的有: 程序代码区、文字常量区、全局静态区。
2,从高到低分配地址的有:栈区
3,堆吗,找到合适的空间就分配,当然无序了。

另外发现:
1,文字常量区总是在程序代码区之后,而全局静态区总是在文字常量区之后。
2,栈区、堆区不会出现在第1条这三者的中间。可能在这他们的前面,也可能后面,也可能两边。
3,在我的电脑上(intel +win10+vs2013)栈区总是在堆区的前面。但在一个代码测试工具的网站上却会出现栈地址在对地址后面的情况。

我电脑上的地址分配就是这个意思

代码区、文字常量区、全局静态区、栈区、堆区的内存空间分布