C语言开发对内存使用有区域划分,分别是栈区、堆区、全局&静态区、文字常量区、程序代码区。注意此处的栈、堆名称有别于数据结构中栈与堆的概念。栈与堆的英文名分别为stack与heap。
栈区:
在函数中定义的变量存放的内存区域。
常见的int、float、char等变量均存放于栈区中,它的特点是由系统自动分配与释放,不需要程序员考虑资源回收的问题,方便简洁。
ps:栈区的地址分配是从内存的高地址开始向地地址分配。
堆区:
程序员通过指令自主向系统申请的内存区域,大小由程序员决定,它在使用完后同样需要程序员通过指令去释放该区域内存,否则将有可能出现内存的浪费与溢出。
C语言中申请堆区指令为:
int *p = (int *) malloc( N * sizeof(int) ); //分配N个int型(4字节)的内存,即 4 * N 个字节
ps:但指针p存放于栈区。
C语言中释放堆区指令为:
free( p ); //注意此处参数为指针
使用中应该注意,尽量不要去修改p指针对应的地址值,否则在内存释放时将出现错误。(编译可通过,运行出现问题)
全局变量&静态变量区:
全局变量与静态变量本应是两个概念,但由于它们在内存中存放的区域相同,所以将他们放在一起讨论。
全局变量:
位于所有函数外部定义的变量,在整个工程中可见,可修改。
静态变量:
位于所有函数内部定义的由 static 修饰的变量,仅在定义的函数中可见,可修改。(这是它与全局变量的关键区别)
ps:静态变量仅在第一次创建时初始化一次,之后自动跳过初始化语句。
全局变量与静态变量均由系统分配和释放内存,若未对它们进行初始化操作,系统将自动将其值设置为0。(堆区与栈区则不会)
文字常量区:
用于存放文字等不可修改的常量,由系统分配和释放内存。
常见的使用:
char *s = "HelloWorld";//该字符串 HelloWorld 即存放于文字常量区,不可修改
ps:但指针s存放于栈区。
pps:若在程序中尝试对其修改(例如尝试修改第一个字符 *s = 'h';),将出现编译可通过,运行报错的情况。
同时因注意它与const修饰的变量之间的区别:
char aa = 'A';//aa存放于栈区
const char bb = 'B'; //bb同样存放于栈区
const修饰的变量仅仅用于告诉编译器bb是一个常量,如果后续的程序中有出现尝试修改bb的操作时,编译将报错。
这种写法主要是为了防止程序员在后续的代码中误操作bb变量而添加的一个约束条件,并不会影响它存放的位置。
程序代码区:
用于存储程序编译连接后生成的二进制机器码指令的内存区域。该部分内容可通过反汇编操作将机器码转换为汇编语言。