数据在内存的存放位置
- 代码部分
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> //用于linux/unix系统的调用,POSIX标准定义的unix类系统定义符号常量的头文件,包含了许多UNIX系统服务的函数原型
static void show_pointer(void *p, char *descr) { //静态函数;入口参数p为空类型指针
//printf("Pointer for %s at %p\n", descr, p);
printf("%s\t%p\t%lu\n", descr, p, (unsigned long) p); //p强制转化为无符号长整型
}
char big_array[1L<<24]; //16 MB
//char huge_array[1L<<31]; //2 GB
char huge_array[1L<<30]; //1 GB
int global = 0; //定义一个全局变量global,并赋值为0
int useless() { return 0; } //定义一个useless函数,无入口参数,返回值为0
int main ()
{
void *p1, *p2, *p3, *p4;
int local = 0; //定义一个局部变量locate并赋值为0
p1 = malloc(1L << 28); //用malloc函数申请2的28次方的空间并将其首地址赋值给p1
p2 = malloc(1L << 8);
//p3 = malloc(1L << 32);
p3 = malloc(1L << 16);
p4 = malloc(1L << 8);
show_pointer((void *) big_array, "big array"); //打印big_array的存放地址,和地址的无符号长整型
show_pointer((void *) huge_array, "huge array");
show_pointer((void *) &local, "local"); //打印局部变量locate的存放地址,和地址的无符号长整型
show_pointer((void *) &global, "global"); //打印全局变量global的存放地址,和地址的无符号长整型
show_pointer((void *) p1, "p1"); //打印p1的存放地址,和地址的无符号长整型
show_pointer((void *) p2, "p2");
show_pointer((void *) p3, "p3");
show_pointer((void *) p4, "p4");
show_pointer((void *) useless, "useless"); //打印函数useless的存放地址,和地址的无符号长整型
show_pointer((void *) exit, "exit"); //打印函数exit的存放地址,和地址的无符号长整型
show_pointer((void *) malloc, "malloc"); //打印函数malloc的存放地址,和地址的无符号长整型
return 0;
}
- 实验结果
内存的分区图如下
(内存中由低到高依次是代码段,数据段,堆,栈)
【我们可以将内存分为五大分区:
1、BSS段( bss segment )
通常是指用来存放程序中未初始化的全局变量和静态变量
2、数据段(data segment)
通常是指用来存放程序中已经初始化的全局变量和静态变量的一块内存区域
3、代码段(code segment/text segment)
通常是指用来存放程序执行代码的一块内存区域
4、堆(heap)
堆是用于存放进程运行中被动态分配的内存段。
当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张); 当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
5、栈 (stack)
栈又称堆栈, 是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}” 中定义的变量(但不不包括static声明的变量,static意味着在数据段中存放变量)
在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。栈先进先出,所以栈特别方便用来保存/恢复调用现场。我们可以把堆栈看成一个寄存、交换临时数据的内存区。】
转载于公众号TeachPlus
我们从代码的运行结果可以看到局部变量locate存放在栈中,全局数组big_array,huge_array,全局变量global是存放在数据段,p1、p2、p3、p4是存放在堆中,useless、exit、malloc是存放在代码段
char big_array[1L<<24]; //16 MB
char huge_array[1L<<31]; //2 GB
//char huge_array[1L<<30]; //1 GB 我们使用上面的char huge_array[1L<<31]
int global = 0;
此时数据区出现了溢出