当前位置:网站首页>[Study Notes Dish Dog Learning C] Dynamic Memory Management
[Study Notes Dish Dog Learning C] Dynamic Memory Management
2022-08-04 02:33:00 【Jiang Junzhu】
一、为什么存在动态内存管理
内存分为三个区,栈区、堆区和静态区(Also called data segment).栈区用来存放局部变量、Temporary variables such as function parameters;The heap area is used for dynamic memory development;静态区用来存放全局变量、静态变量等.
形如int val = 20;、char arr[10] = {0};The way of memory development is to open up on the stack space, Its space development size is fixed,And when declaring the array,必须指定数组的长度,它所需要的内存在编译时分配.
But sometimes the amount of space we need can only be known when the program is running,那数组的编译时开辟空间的方式就不能满足了,这时候就只能试试动态存开辟了.
二、Introduction to Dynamic Memory
1、malloc函数和free函数
- malloc函数介绍

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针;
如果开辟成功,则返回一个指向开辟好空间的指针;
如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查;
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定;
如果参数size为0,malloc的行为是标准是未定义的,取决于编译器.
- free函数介绍

C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的;
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的;
如果参数 ptr 是NULL指针,则函数什么事都不做.
- 代码实例
int main() {
//假设开辟10个整型空间 - 10* sizeof(int)
//动态内存开辟空间
int* p = (int*)malloc(10 * sizeof(int));//void*
//使用这些空间的时候
if (NULL == p) {
//printf + strerror
perror("main");//main:xxxxxxxxxxxxx
return 0;
}
//使用
int i = 0;
for (i = 0; i < 10; i++) {
*(p + i) = i;
printf("%d\n", *(p + i));
}
for (i = 0; i < 10; i++) {
printf("%d ", p[i]);//p[i] --> *(p + i)
}
//回收空间
free(p);
p = NULL;//手动把p置为NULL,Prevent access from out of bounds,造成野指针
return 0;
}
malloc基本上和free是成对出现的.
2、calloc函数
- calloc函数介绍

函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0;
与函数malloc的区别只在于calloc会在返回地址之前把申请的空间的每个字节初始化为全0.


- 代码实例
int main() {
int* p = calloc(10, sizeof(int));
if (NULL == p)
return 1;
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d\n", *(p + i));
}
free(p);
p = NULL;
return 0;
}
3、realloc函数
- realloc函数介绍

ptr 是要调整的内存地址;
size 调整之后新大小;
返回值为调整之后的内存起始位置;
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到 新 的空间;
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间
情况一:
情况二:
- 代码实例
int main() {
int* p = calloc(10, sizeof(int));
if (NULL == p) {
perror("mian");
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++) {
printf("%d\n", *(p + i));
}
//这里需要p指向的空间更大,需要20个int函数
//realloc调整空间
int* ptr = realloc(p, 20 * sizeof(int));
if (ptr != NULL) {
p = ptr;
}
free(p);
p = NULL;
return 0;
}
三、常见动态内存错误
- 对NULL指针进行解引用操作
void test()
{
int* p = (int*)malloc(INT_MAX / 4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
- 对动态开辟的空间越界访问
void test()
{
int i = 0;
int* p = (int*)malloc(10 * sizeof(int));
if (NULL == p)
{
exit(EXIT_FAILURE);
}
for (i = 0; i <= 10; i++)
{
*(p + i) = i;//当i是10的时候越界访问
}
free(p);
}
- 对非动态开辟的内存使用free释放
void test()
{
int a = 10;
int* p = &a;
free(p);//ok?
}
- 使用free释放一块动态开辟内存的一部分
void test()
{
int* p = (int*)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
- 对同一块动态内存多次释放
void test()
{
int* p = (int*)malloc(100);
free(p);
free(p);//重复释放
}
- 动态开辟内存忘记释放,导致内存泄露
void test()
{
int* p = (int*)malloc(100);
if (NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while (1);
}
边栏推荐
猜你喜欢

关联接口测试

Kubernetes:(九)coredns(浪不动了)

参加Oracle OCP和MySQL OCP考试的学员怎样在VUE预约考试

Dong mingzhu live cold face away, when employees frequency low-level mistakes, no one can understand their products

STM8S105k4t6c--------------点亮LED

Kubernetes:(十一)KubeSphere的介绍和安装(华丽的篇章)

共n级台阶,每次可以上1级或2级台阶,有多少种上法?

Rongyun "Audio and Video Architecture Practice" technical session [complete PPT included]

深度学习(三)分类 理论部分

如何在MySQL中的数据库下删除所有的表
随机推荐
C语言力扣第54题之螺旋矩阵。模拟旋转
Continuing to invest in product research and development, Dingdong Maicai wins in supply chain investment
实例037:排序
小程序+新零售,玩转行业新玩法!
架构实战营模块三作业
Development of Taurus. MVC WebAPI introductory tutorial 1: download environment configuration and operation framework (including series directory).
ssh服务详解
Sky map coordinate system to Gaode coordinate system WGS84 to GCJ02
Parquet encoding
In the season of going overseas, the localization of Internet tips for going overseas
倒计时2天,“文化数字化战略新型基础设施暨文化艺术链生态建设发布会”启幕在即
如何在MySQL中的数据库下删除所有的表
DHCP服务详解
可变字符串
2022年T电梯修理考题及答案
大佬们,读取mysql300万单表要很长时间,有什么参数可以优惠,或者有什么办法可以快点
Instance, 038: the sum of the diagonal matrix
2022.8.3-----leetcode.899
持续投入商品研发,叮咚买菜赢在了供应链投入上
flask框架初学-06-对数据库的增删改查