全国住房建设部网站,广西seo优化,福州 哈尔滨网站建设 网络服务,wordpress后端页面开发目录 引言
一、为什么要有动态内存分配#xff1f;
二、malloc
三、free
四、calloc
五、realloc
六、常见的动态内存错误
1、对 NULL 的解引用
2、对动态内存开辟空间的越界访问
3、对非动态内存开辟的空间使用 free
4、用 free 释放动态内存空间的一部分
5、对同…目录 引言
一、为什么要有动态内存分配
二、malloc
三、free
四、calloc
五、realloc
六、常见的动态内存错误
1、对 NULL 的解引用
2、对动态内存开辟空间的越界访问
3、对非动态内存开辟的空间使用 free
4、用 free 释放动态内存空间的一部分
5、对同一空间的反复释放 七、结语 引言
在编写高效且灵活的C语言程序时内存管理扮演着至关重要的角色。静态分配虽然简单易用但在面对变长数据结构和复杂需求时动态内存管理提供了更强的弹性。通过合理地申请、使用和释放内存我们不仅可以优化资源利用还能避免潜在的内存泄漏问题。本篇博客将带你全面了解C语言中的动态内存管理机制掌握相关的核心技术与实践技巧。 一、为什么要有动态内存分配
因为灵活。现实情况中有很多的不确定因素不确定的数量不确定的大小如果设置的容量小了不够用大了又会浪费空间这时候就绪需要用到动态内存来灵活的设置容量大小。 二、malloc
该函数包含在 stdlib.h 中它的原型如下
void* malloc(size_t size);
功能向内存的堆区申请一块连续可用的空间
返回如果申请成功则返回这块空间的地址 申请失败则返回 NULL
举个栗子
//向内存申请一块连续的能放下10个整型的空间
int* ret (int*)malloc(10 * sizeof(int));
//判断申请是否成功
if (ret NULL)
{perror(malloc);return 1;
}
注意malloc 的返回值为 void* 类型因此我们需要对齐强制类型转换转换为你想要的类型int* , char* 等等甚至结构体指针 三、free
该函数包含在头文件 stdlib.h 中它的原型如下
void free(void* ptr); 功能释放开辟的动态内存
无返回值
举个例子
//释放掉刚才开辟的空间
free(ret);
ret NULL; //防止野指针
在我们用完一块空间后一定要记得释放不然指向该空间的指针被修改或者销毁那么你将永远找不到这块空间而这块空间还在占用你的内存 四、calloc
该函数包含在 stdlib.h 中它的原型如下
void* calloc(size_t num, size_t size);
功能为 num 个大小为 size 的元素开辟一块空间
返回成功返回空间地址失败返回 NULL
举个栗子
//向内存申请一块连续的能放下10个整型的空间
int* p (int*)calloc(10 ,sizeof(int));
//判断申请是否成功
if (p NULL)
{perror(malloc);return 1;
}
//……使用
//释放
free(p);
p NULL;
注意calloc 与 malloc 一样都用于开辟一块动态内存不同的是calloc 会给每个空间初始化为 0 而 malloc 不会 五、realloc
该函数也是包含在 stdlib.h 中它的原型如下
void* realloc(void* ptr, size_t size);
功能调整动态内存的大小
ptr 被调整的空间地址
size 调整之后的新大小单位是字节
返回成功返回调整之后的新地址 失败返回 NULL
举个栗子
//向内存申请一块连续的能放下10个整型的空间
int* p (int*)calloc(10 ,sizeof(int));
//判断申请是否成功
if (p NULL)
{perror(malloc);return 1;
}
//调整大小为80个字节
int* p2 (int*)realloc(p, 40 40);
//判断是否调整成功
if( p2 NULL)
{perror(realloc);return 1;
}
p p2;
//释放
free(p);
p NULL;
这里为什么要用 p2 接收扩容后的空间呢
因为如果扩容失败realloc 就会返回 NULL如果用原来的 p 去接收那么 p 就被置为 NULL那么原来的那块空间就彻底跟你 say 拜拜了
那么realloc 的细节是什么真的是扩容吗
其实不是的realloc 只是申请一块新的空间然后把源空间的内容拷贝到新空间然后在返回新空间的地址 六、常见的动态内存错误
1、对 NULL 的解引用
平时大家肯定不会反这种错误但有时候 NULL 会伪装自己蒙蔽了广大学者的慧眼比如
int* p (int*)malloc(INT_MAX);
for (int i 0; i 10; i)
{p[i] i;
}
INT_MAX 是有符号int类型的最大值 21247483647 很大的一个数字就会让内存申请失败返回NULL而这时候在解引用就会报错
为了规避这种错误建议每申请完一个空间都要对齐判断是否成功
2、对动态内存开辟空间的越界访问
int* p (int*)malloc(10 * sizeof(int));
if (p NULL)
{perror(malloc);return 1;
}
for (int i 0; i 10; i)
{p[i] i;
}
当 i 10 时越界访问
这个问题都是很常见的这里就不多说了
3、对非动态内存开辟的空间使用 free
注意free 只能释放动态内存空间也就是用 malloc calloc realloc 开辟出来的空间至于数组什么的都不可以
4、用 free 释放动态内存空间的一部分
int* p (int*)malloc(10 * sizeof(int));
p p 2;
free(p);
这样也不可以free 必须接收该空间的首地址
5、对同一空间的反复释放 int* p (int*)malloc(10 * sizeof(int));if (p NULL){perror(malloc);return 1;}free(p);free(p);
这种也是不可以滴但是为了避免这种错误可以在每次释放后给 p 置为 NULL 七、结语
掌握C语言的动态内存管理不仅是写出高效程序的关键也是开发安全稳健软件的重要保障。善用malloc、realloc和free等函数我们可以灵活应对各种复杂场景实现资源的动态高效利用。在未来的编程旅程中让我们不断深入探索与实践成为内存管理的高手从而写出更加出色与安全的C语言程序。