标签:
bss段用来存放 没有被初始化 和 已经被初始化为0 的全局变量。如下例代码:
#include<stdio.h> int bss_array[1024*1024]; int main(int argc, char *argv[]) { return 0; }
编译并查看:
$ gcc -g mainbss.c -o mainbss $ ls -l mainbss -rwxrwxr-x. 1 hy hy 8330 Apr 22 19:33 mainbss $ objdump -h mainbss |grep bss mainbss: file format elf32-i386 24 .bss 00400020 0804a020 0804a020 00001018 2**5
$ size mainbss text data bss dec hex filename 1055 272 4194336 4195663 40054f mainbss
全局变量bss_array的大小为4MB = 1024*1024*sizeof(int) Byte = 4194304 Byte。 通过size 查看可知数据被存在了 bss 段
而 可执行文件mainbss 有8KB左右。可知,bss类型的全局变量只占用 运行时的内存空间,而不占用可执行文件自身的文件空间。
data段用来存放已经被初始化为非零的全局变量。如下代码,只将矩阵的第一个元素初试化为1:
#include<stdio.h> int data_array[1024*1024]={1}; int main(int argc, char *argv[]) { return 0; }
编译查看
[hy@localhost memcfg]$ gcc -g maindata.c -o maindata [hy@localhost memcfg]$ ls -l maindata -rwxrwxr-x. 1 hy hy 4202682 Apr 22 19:48 maindata [hy@localhost memcfg]$ objdump -h maindata |grep \\.data 23 .data 00400020 0804a020 0804a020 00001020 2**5 [hy@localhost memcfg]$ size maindata text data bss dec hex filename 1055 4194604 4 4195663 40054f maindata
而 可执行文件maindata 有4MB左右。通过size 查看可知数据被存在了 data 段
可知,data类型的全局变量既占用运行时的内存空间,也占用可执行文件自身的文件空间。
1)rodata用来存放常量数据。 ro: read only
2)字符串会被编译器自动放在rodata中,加 const 关键字的常量数据会被放在 rodata 中
3)在有的嵌入式系统中, rodata放在 ROM(或 NOR Flash)里,运行时直接读取,不须加载到RAM内存中。
所以,在嵌入式开发中,常将已知的常量系数,表格数据等造表加以 const 关键字。存在ROM中,避免占用RAM空间。
text段存放代码(如:函数)和部分整数常量(应该指的是一些立即数),这个段是可执行的。
1)stack 存放函数的局部变量和函数参数
2)被调用函数的参数和返回值 被存储到当前程序的栈区,之后被调用函数再为自身的自动变量和临时变量在栈区上分配空间
3)函数返回时,栈区的数据会被释放掉,先入后出(FILO)的顺序。
heap用来动态分配内存,由程序自身决定开辟和释放。
#include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { int *p = (int *)malloc(10*1); // p= (int *)malloc(10*1); if(p==NULL) { printf("malloc p err\n"); return -1; } free(p); printf("p = %4x\n",p); p = NULL; printf("p = %4x\n",p); return 0; }
程序运行结果:
[hy@localhost memcfg]$ gcc maindata.c [hy@localhost memcfg]$ ./a.out p = 9cf4008 p = 0
1)开辟了空间,就要适时的释放。释放时,指针应指向开辟时的内存空间,所以在使用指针时,要注意不要修改了其地址,或者将开辟时的起始地址保存起来。
2)对指针free后,其地址不一定就为NULL。如代码中的 p,在 free(p)后,printf(p)后并非为0。所以建议在free(p)后,立即加一句p=NULL。
3)检查p的地址 if(p!=NULL){ ... }
1)calloc()函数
void *calloc(size_t nmemb, size_t size);
参数nmemb 表示要分配元素的个数,size表示每个元素的大小,分频的内存空间大小是 nmemb*size; 返回值是 void* 类型的指针,指向分配好的内存首地址。
用法一:分配1024*sizeof(int)字节大小的内存,并清空为0
int *p = (int *)calloc(1024,sizeof(int));
用法二:与 alloc等价的 malloc 用法
int *p = (int *)malloc(1024*sizeof(int)); memset(p,0,1024*sizeof(int));
差异:用法一,会根据分配的的类型来初始化为0,如:分配int型,则初始化为(int)0; 若为指针类型,则初始化为空指针;若为浮点,则初始化为浮点型。
用法二,不成保证初试化为空指针值和浮点型。(与NULL常量和浮点型的定义有关)
2)realloc()函数
realloc()用来重新分配正在使用的一块内存大小。
定义:
void *realloc(void *ptr, size_t size);
用法示例:
int *p = (int *)malloc(1024); // p = (int *)realloc(512); // 重新分配为 512字节大小内存,缩小数据丢失 p = (int *)realloc(2048); // 重新分配为2048字节大小内存
注意:经过realloc()调整后的内存空间起始地址有可能与原来的不同。
《ARM嵌入式Linux系统开发详解》 弓雷 等编著
《高质量嵌入式Linux C编程》 梁庚 等编著
笔记:程序内存管理 .bss .data .rodata .text stack heap
标签:
原文地址:http://www.cnblogs.com/hythink/p/5422602.html