当前位置:网站首页>动态内存开辟(C语言)
动态内存开辟(C语言)
2022-08-05 08:33:00 【InfoQ】
推荐一个C语言手册网站:cplusplus.com
头文件: #include<stdlib.h>
#include<malloc.h>
内存的三个区域
如下图所示

为什么要使用动态内存开辟
目前我们所知道的向内存申请空间的方法有两种:
(1)创建一个变量(如 int a; 就向内存申请了四个字节的空间大小)。
(2)创建一个数组。
但比如创建一个50元素的数组(int a[50])就一定会发生内存浪费或者不够的现象,
为了使用多大内存就申请多大内存的空间
,我们就可以使用动态内存开辟(在堆区)。
动态内存分配的函数
free
函数free专门是用来做动态内存的释放和回收的,即当动态申请的空间不再使用时,应还给操作系统。
说简单点就是你申请了就要还回去。
虽然不用free函数,在程序执行结束后,系统会自动将你申请的内存释放,但如果你申请过一次,还剩空间不想用了,主程序又没执行完,那你应该先释放掉这些内存,让给别人申请使用。
使用方法:
比如之前你定义了一个指针p,在结尾用
free(p);
p=NULL;
Q:
为什么还要把p赋值成空指针呢?我不是已经释放掉了吗?
A:
p虽然还给操作系统,但依然有能力找到你刚才申请的这块空间,所以再给p赋一个空指针。
malloc
翻阅手册我们可以看到malloc函数的使用为
void* malloc (size_t size);直接上案例
int* p = (int*) malloc (10* sizeof(int));
(1)上面的代码就是向内存申请了10个int字节的空间,现在的编译器中int一般为4字节大小,10个int就是40字节大小,也可以直接打40。
(2)因为malloc的返回类型为void* ,会报警告,需要强制类型转换。
(3)当没有足够的空间时,malloc会返回一个
空指针
(NULL)。
打印错误原因的一种方式
这个算是题外话了。
当我们想知道我们程序什么出错时(比如内存申请失败)。可以用下面的函数。
#include<string.h>
#include<errno.h>
#include<stdio.h>
printf("%s\n",strerror(errno));
stdio.h对应printf , errno.h对应errno , string.h对应strerror
由malloc和free的实例演示
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
printf("%s\n", strerror(errno));
else
{
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
}
free(p);
p = NULL;
return 0;
}
注释:(1)引入头文件不可少。
(2)这里我申请了40个字节空间大小(10*sizeof(int) ),并用一个int *类型的指针p指向了这个空间的首地址。
(3)if语句判断申请内存成不成功,还记得我们上面说的吗?当没有足够的空间时,malloc会返回一个空指针(NULL)。
(4)else语句里是将0-9这些数字放入这些内存当中,i=0时
p=0,i=1时,
(p+1)=1。以此类推
(5)打印出放入到这块空间的数字。
(6)释放掉这块空间,将p赋为空指针。
打印出的结果如下

注:如果使用比较新的vs(比如2022版)使用strerror时要在程序最上面加上
#define _CRT_SECURE_NO_WARNINGS
realloc
realloc的作用是可以调整动态开辟内存空间的大小。
假设本来使用malloc申请20字节空间,不够了,我希望有40字节空间。
那么就可以使用以下代码
int* p = (int*)malloc(20);
int* p2 = realloc(p, 40);
注意事项:
Q:
为什么用一个新的p2不再用p?
(1)如果p指向的空间之后有足够的内存空间可以追加,则直接追加,后返回p。
(2)如果p指向的空间之后没有足够的空间可以追加,则ralloc函数会重新找一个新的内存南区域开辟一块满足需求的空间,
并且把原来内存中的数据拷贝回来
,释放旧的内存空间,最后返回新开辟的内存空间地址。
Q:
如果我还是想用原来的p不用p2怎么办?
(3)要用一个新变量接受realloc函数的返回值(上面就用的是p2)
看代码如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
int* p = (int*)malloc(20);
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
else
{
int i = 0;
for (i = 0; i < 5; i++)
{
*(p + i) = i;
}
}
int* p2 = realloc(p, 40);
if (p2 != NULL)
{
p = p2; //把p2的首地址又给了p,做到了衔接
int i = 0;
for (i = 5; i < 10; i++)
{
*(p + i) = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", *(p + i));
}
}
free(p);
p = NULL;
return 0;
}
边栏推荐
猜你喜欢
随机推荐
谷歌零碎笔记之MVCC(草稿)
egg框架
支持触屏slider轮播插件
Long-term recruitment embedded development-Shenzhen Baoan
Qt writes custom controls: one of the text spotlight effects
【结构体内功修炼】结构体内存对齐(一)
程序设计中的感悟
Luogu P4588: [TJOI2018]数学计算
tear apart loneliness
Thinking after writing a code with a very high CPU usage
MM上街前的折腾(有趣)
苹果官网商店新上架Mophie系列Powerstation Pro、GaN充电头等产品
小本创业者的致胜法宝!
Adb authorization process analysis
基于多块信息提取和马氏距离的k近邻故障监测
复现一次循环和两次循环
php fails to write data to mysql
路由----router
写出了一个CPU占用极高的代码后引发的思考
Constellation ideal lover









