为了能够反应上述内存分布情况,这里在《UNIX 环境高级编程》的程序 14-11 的基础上,添加了一个已经初始化的全局变量(存放在已经初始化的数据段内),并打印了它以及 main 函数(处在代码正文部分)的位置。
/**
* showmemory.c -- print the position of different types of data in a program in the memory
*/
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 4000
#define MALLOC_SIZE 100000
#define SHM_SIZE 100000
#define SHM_MODE (SHM_R | SHM_W) /* user read/write */
int init_global_variable = 5; /* initialized global variable */
char array[ARRAY_SIZE]; /* uninitialized data = bss */
int main(void)
{
int shmid;
char *ptr, *shmptr;
printf("main: the address of the main function is %x\n", main);
printf("data: data segment is from %x\n", &init_global_variable);
printf("bss: array[] from %x to %x\n", &array[0], &array[ARRAY_SIZE]);
printf("stack: around %x\n", &shmid);
/* shmid is a local variable, which is stored in the stack, hence, you
* can get the address of the stack via it*/
if ( (ptr = malloc(MALLOC_SIZE)) == NULL) {
printf("malloc error!\n");
exit(-1);
}
printf("heap: malloced from %x to %x\n", ptr, ptr+MALLOC_SIZE);
if ( (shmid = shmget(IPC_PRIVATE, SHM_SIZE, SHM_MODE)) < 0) {
printf("shmget error!\n");
exit(-1);
}
if ( (shmptr = shmat(shmid, 0, 0)) == (void *) -1) {
printf("shmat error!\n");
exit(-1);
}
printf("shared memory: attached from %x to %x\n", shmptr, shmptr+SHM_SIZE);
if (shmctl(shmid, IPC_RMID, 0) < 0) {
printf("shmctl error!\n");
exit(-1);
}
exit(0);
}
该程序的运行结果如下:
$ make showmemory
cc showmemory.c -o showmemory
$ ./showmemory
main: the address of the main function is 804846c
data: data segment is from 80498e8
bss: array[] from 8049920 to 804a8c0
stack: around bfe3e224
heap: malloced from 804b008 to 80636a8
shared memory: attached from b7da7000 to b7dbf6a0
上述运行结果反应了几个重要部分数据的大概分布情况,比如 data 段(那个初始化过的全局变量就位于这里)、bss 段、stack、heap,以及 shared memory 和main(代码段)的内存分布情况。
$ nm showmemory
080497e4 d _DYNAMIC
080498b0 d _GLOBAL_OFFSET_TABLE_
080486c8 R _IO_stdin_used
w _Jv_RegisterClasses
080497d4 d __CTOR_END__
080497d0 d __CTOR_LIST__
080497dc d __DTOR_END__
080497d8 d __DTOR_LIST__
080487cc r __FRAME_END__
080497e0 d __JCR_END__
080497e0 d __JCR_LIST__
080498ec A __bss_start
080498dc D __data_start
08048680 t __do_global_ctors_aux
08048414 t __do_global_dtors_aux
080498e0 D __dso_handle
w __gmon_start__
0804867a T __i686.get_pc_thunk.bx
080497d0 d __init_array_end
080497d0 d __init_array_start
08048610 T __libc_csu_fini
08048620 T __libc_csu_init
U __libc_start_main@@GLIBC_2.0
080498ec A _edata
0804a8c0 A _end
080486a8 T _fini
080486c4 R _fp_hw
08048328 T _init
080483f0 T _start
08049920 B array
08049900 b completed.1
080498dc W data_start
U exit@@GLIBC_2.0
08048444 t frame_dummy
080498e8 D init_global_variable
0804846c T main
U malloc@@GLIBC_2.0
080498e4 d p.0
U printf@@GLIBC_2.0
U shmat@@GLIBC_2.0
U shmctl@@GLIBC_2.2
U shmget@@GLIBC_2.0