内存分配
C大约 2 分钟...
内存是计算机中非常稀有的资源,了解一个内存的架构,如何理解操作系统管理内存,作为一个程序员更好的使用内存是非常有必要的
在一个典型的架构中,分配给应用程序的内存被分为 4 个区段:
- 堆区 - 动态内存,可以分配任意大小的内存,只要不超过计算机内存的可用容量,堆并不是数据结构中的堆实现
- 栈区 - 用于存放函数调用时的所有信息,包括所有的局部变量,生命周期只存在函数运行期间
- 静态/全局数据段 - 不在函数中定义的变量,生命周期贯穿整个程序
- 代码段 - 存放程序执行的指令
栈区、静态/全局数据段、代码段在运行期间的大小是不会增长的
在栈中执行的函数永远都是栈顶的函数在执行,其他的函数暂停执行等待上面的函数执行完,然后自动回收空间。main
函数永远都处于栈底,因为它是程序的入口,也是出口。如果在运行期间耗尽了栈空间,就会产生栈溢出现象,导致程序崩溃
而堆是由程序员自己可以分配的内存空间,由程序员手动分配,手动回收,一切都交给程序员来决定。C 提供了四个函数用来操作堆,它们都由stdlib.h
提供:
malloc(size)
- 在堆中分配指定字节大小的空间,并返回一个指向该内存起始地址的void
类型指针,不会初始化,会得到垃圾值calloc(num, size)
- 和malloc
差不多,但是会初始化值为0
realloc(void *ptr, size)
- 重新分配通过malloc/calloc
分配的内存空间并拷贝数据,可以增大或减小,并返回指向该起始地址的void
类型指针free(void *ptr)
- 释放指定地址的内存空间
int a;
int *p;
// 在堆中分配 sizeof(int) 大小的空间
p = (int *)malloc(sizeof(int));
*p = 1;
printf("%d", *p); // 1
如果malloc
找不到内存中可分配的内存块就会返回NULL
之前无法在运行期间指定数组大小的问题,也可以通过动态内存分配来解决了
#include <stdio.h>
#include <stdlib.h>
int main(void){
int n;
scanf("%d", &n);
int arr = (int *)malloc(n * sizeof(int));
return 0;
}