1.典型的内存分布情况:
2.各段相关说明:
- 代码段[.text]: 存储机器码序列/全局常量/代码/字符串常量.
- 初始化数据段: 初始化的全局变量/初始化的(局部/全局)静态变量(static修饰的变量)。
- 未初始化数据段[.bbs]: 未初始化的全局变量/未初始化的(局部/全局)静态变量(static修饰的变量).
- 堆(从低地址往高低至增长): 所使用的局部变量还是在栈上,内容则在堆上.手动释放或者程序结束时由操作系统释放回收.
* 由程序员分配[new/malloc/realloc/calloc].
* windows下, 申请的堆空间一般小于2GB。 - 栈(从高地址往低地址增长): 局部变量/局部常量(const)[局部只读变量]/函数调用时返回地址/调用者的环境信息(例如某些机器寄存器).
- 由编译器自动分配释放管理.
- windows下,申请的栈空间一般为2MB。
- Linux默认的栈空间是8MB,可以用ulimit -s 命令来修改。
3.注:
1). 对于32位Intel x86 处理器上的linux, 正文段(.text)从0x8048000单元(每个程序都虚拟一个)开始,栈底则在0xC0000000之下开始.
4. 相关文章:
1). 关于static:
2). 关于const[#define]:
5. 相关代码:
1). 输出各种变量,数据的位置信息
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
static int init_static = 10;
static int uninit_static ;
int init_overall = 20;
int uninit_overall;
char *init_str_overall = "str_overall";
char *uninit_str_overall;
char init_strArray_overall[20]= "strArray_overall";
char uninit_strArray_overall[20];
int main(void)
{
static int init_static_part = 30;
static int uninit_static_part;
int init_part = 40;
int uninit_part;
char *p = (char *)malloc(sizeof(char) * 8);
char *str = "ABCDEFG";
char init_strArray[10] = "BCDEFGH"; !!!注意这个,值也是在栈中!!!
char uninit_strArray[10];
printf("全局静态初始化变量: 变量的地址 = (数据段)%p, 值的地址:%p\n", &init_static, &init_static);
printf("全局静态初未始化变量: 变量的地址 = (数据段)%p, 值的地址:%p\n", &uninit_static, &uninit_static);
printf("全局初始化变量: 变量的地址 = (数据段)%p, 值的地址:%p\n", &init_overall, &init_overall);
printf("全局未初始化变量: 变量的地址 = (数据段)%p, 值的地址:%p\n", &uninit_overall, &uninit_overall);
printf("!!!全局初始化指针字符串: 变量的地址 = (数据段)%p, 值的地址:(代码段)%p\n", &init_str_overall, init_str_overall);
printf("!!!全局未初始化指针字符串: 变量的地址 = (数据段)%p, 值的地址:()%p\n", &uninit_str_overall, uninit_str_overall);
printf("!!!全局初始化字符串数组: 变量的地址 = (数据段)%p, 值的地址:(数据段)%p\n", &init_strArray_overall, init_strArray_overall);
printf("!!!全局未初始化字符串数组: 变量的地址 = (数据段)%p, 值的地址:(数据段)%p\n", &uninit_strArray_overall, uninit_strArray_overall);
printf("局部静态初始化变量: 变量的地址 = (数据段)%p, 值的地址:%p\n", &init_static_part, &init_static_part);
printf("局部静态未初始化变量: 变量的地址 = (数据段)%p, 值的地址:%p\n", &uninit_static_part, &uninit_static_part);
printf("局部初始化变量: 变量的地址 = (栈)%p, 值的地址:%p\n", &init_part, &init_part);
printf("局部未初始化变量: 变量的地址 = (栈)%p, 值的地址:%p\n", &uninit_part, &uninit_part);
printf("!!!局部动态分配变量: 变量的地址 = (栈)%p, 值的地址:(堆)%p\n", &p, p);
printf("!!!局部初始化指针变量: 变量的地址 = (栈)%p, 值的地址:(代码段)%p\n", &str, str);
printf("!!!局部初始化字符数组: 变量的地址 = (栈)%p, 值的地址:(数据段)[错!]%p\n", &init_strArray, &init_strArray[0]);
printf("!!!局部未初始化字符数组: 变量的地址 = (栈)%p, 值的地址:(数据段)[错!]%p\n", &uninit_strArray, &uninit_strArray[0]);
return 0;
}