四个操作内存的函数
| 函数名********************** |
作用 |
| malloc |
申请空间(连续) |
| calloc(了解) |
申请空间+数据初始化 |
| realloc(了解) |
修改空间大小 |
| free |
释放空间 |
#include<stdio.h>
#include<stdlib.h>
int main()
{
// 申请一片连续内存空间
printf("申请一片连续内存空间:\n");
int* p = malloc(10 * sizeof(int));
// 赋值
for (int i = 0; i < 10; i++)
{
// 赋值方法一
//*(p + i) = (i + 1) * 10;
// 赋值方法二
p[i] = (i + 1) * 10;
}
// 遍历数据
for (int i = 0; i < 10; i++)
{
//printf("%d ", *(p + i));
printf("%d ", p[i] );
}
// 申请空间+数据初始化 (了解)
printf("\n\n申请空间+数据初始化 (了解):\n");
int* p2 = calloc(10, sizeof(int));
// 遍历数据
for (int i = 0; i < 10; i++)
{
printf("%d ", p2[i]);
}
// 修改空间大小
printf("\n\n修改空间大小:\n");
int* pp = realloc(p, 20);
// 遍历数据
for (int i = 0; i < 10; i++)
{
printf("%d ", pp[i]);
}
// 释放空间
printf("\n\n释放空间:\n");
free(p2);
// 遍历数据
for (int i = 0; i < 10; i++)
{
printf("%d ", p2[i]);
}
printf("\n");
return 0;
}
细节
malloc
- 创建空间的单位是字节
- 返回的是void类型的指针,没有步长的概念,也无法获取空间中的数据,需要强转
- 返回的仅仅是首地址,没有总大小,最好定义一个变量记录总大小
- 申请的空间不会自动消失,如果不能正确释放,会导致内存泄露
- 申请内存过多时,会产生虚拟内存(申请的内存如果没有用的话,是不会圈起来的,而是等用到的时候再在内存中开辟)
- 申请的空间没有初始化赋值,需要赋值后才能使用
free
- 释放完空间后,空间中数据叫做脏数据,可能被清空,可能被修改成其他值
callloc
realloc
- 修改后的空间,地址有可能发生变化,也有可能不会变化,但是原有的数据不会丢失
- 修改之后,如果内存地址发生了变化,那么函数底层会将原地址处的空间顺手释放掉,不用手动释放
C语言的内存结构
![image-20260314180831816]()
| 内存类型 |
放置类型 |
| 代码区 |
运行时代码 |
| 栈 |
函数运行区域(如果有变量/数组的话,也会存在这里,前提是没有用static修饰) |
| 初始化静态区 |
static全局变量(已初始化) |
| 未初始化静态区 |
static全局变量(未初始化) |
| 常量区 |
(指针定义的)字符串 |
| 堆 |
malloc,calloc,realloc函数 |