概要
C语言的内存存储是一个复杂但非常重要的主题,涉及到静态内存、动态内存、指针、堆栈等多种机制,明白了c语言的内存分配,可以帮助我们更好的编程和学习c语言。
一.内存分配的类型
在C/C++中内存分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。
静态内存分配:编译时分配。包括:全局、静态全局、静态局部三种变量。
动态内存分配:运行时分配。包括:栈(stack): 局部变量。堆(heap): c语言中用到的变量被动态的分配在内存中。(malloc或calloc、realloc、free函数)
二.变量的内存分配
1.代码段
代码段也叫text段,是存放源程序的二进制代码。
2.常量存储区(const)
常量存储区也叫 data段,用来保存全局的和静态的已初始化变量,比如 int a=2;
储存在常量区的只读不可写,const修饰的全局变量也储存在常量区,const修饰的局部变量依然在栈上。
3.静态储存区(static)
静态储存区也叫 bss 段,保存全局的和静态的未初始化变量,比如 int a;
这块空间当程序运行结束后由系统释放。
4.堆
- 堆(Heap):用来存储程序运行时分配的变量
- 堆的大小并不固定,可动态扩张和缩减。其分配由malloc(),或者new(),等函数实现分配
- 当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张)
- 当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被压缩)
- 堆的内存释放由应用程序去控制,通常一个new()就要对应一个delete(),如果程序员没有释放,那么在程序结束后操作系统会自动回收
5.栈
- 栈(stack)是一种用来存储函数调用时的临时信息的结构,如函数调用所传递的参数,函数的返回值,函数的局部变量等。在程序运行时由编译器在需要的时候分配,在不需要的时候自动清楚
- 栈的特性:最后一个放入栈中的物体总是被先拿出来,这个特性通常称为先进后出(FILO)队列
- 栈的基本操作:PUSH操作,想栈中添加数据,称为压栈。将数据放置在栈顶
- POP操作:POP操作相反,在栈顶部移去一个元素,并将栈的大小减一,称为弹栈。
三.动态分配内存
malloc
malloc
是 C 语言中的一个函数,用于动态内存分配。它的全称是 "memory allocation",中文意思是动态内存分配。malloc
函数的主要作用是在程序运行时根据需要分配指定大小的内存空间,并返回一个指向该内存块的指针。这种方式允许程序在运行时灵活地管理内存,而不是在编译期间预设固定的内存空间
void* malloc(size_t size);
其中,size
是要求分配的字节数,返回值是一个指向分配内存的指针。如果分配失败,则返回 NULL
。
使用 malloc
函数需要包含头文件 <stdlib.h>
int *p;
p = (int *)malloc(sizeof(int))
在这个例子中,malloc
分配了一个 int
类型大小的内存空间,并将其地址赋值给指针 p
。注意,malloc
返回的是 void*
类型,因此需要进行类型转换
malloc注意事项
在这个例子中,malloc
分配了一个 int
类型大小的内存空间,并将其地址赋值给指针 p
。注意,malloc
返回的是 void*
类型,因此需要进行类型转换