个人主页
:古德猫宁-
本节目标:
前面的文章介绍了C语言的动态内存开辟,本文重点讲述常见的动态内存的错误
void test()
{
int* p = (int*)malloc(sizeof(int));
*p = 20;
free(p);
}
解释:
这段代码的主要目的是使用动态内存分配(malloc)为一个整数分配内存,将其值设置为 20,然后使用 free 函数释放该内存。从代码的角度来看,没有显著的问题,但是有一些潜在的注意事项:
在实际的程序中,最好在调用 malloc 后检查分配是否成功。如果内存分配失败,malloc 将返回 NULL,释放内存后,我们最好将指针置为 NULL,以避免悬挂指针问题
修改后:
void test()
{
int* p = (int*)malloc(10*sizeof(int));
*p = 20;//如果p的值是NULL,就会有问题
if (p == NULL)//判断分配是否成功
{
perror("malloc");//报错
return 1;
}
free(p);//释放空间
p = NULL;
}
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
int i = 0;
for (i = 0; i <= 10; i++)
{
*(p + i) = i;//当循环到第11次时就越界访问了
}
//
free(p);
p = NULL;
return 0;
}
上面这段代码中使用 malloc 分配了 40 字节的内存,然后在循环中尝试写入 11 个整数。由于数组索引是从 0 开始的,因此当 i 等于 10 时,实际上是在访问 *(p + 10),这越过了为数组分配的内存范围。
所以我们可以这样改:
#include
int main()
{
int* p = (int*)malloc(11*sizeof(int));//分配足够的空间来存储11个整数
if (p == NULL)
{
return 1;
}
//使用
int i = 0;
for (i = 0; i <=11; i++)
{
*(p + i) = i;//循环的上限改为 10,不会越界访问
}
//
free(p);
p = NULL;
return 0;
}
int main()
{
int a = 10;
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
//...
p = &a;//p指向的空间就不再是堆区上的空间
free(p);
p = NULL;
//....
return 0;
}
修改后:
#include
int main() {
int a = 10;
int* p = (int*)malloc(40);
if (p == NULL) {
return 1;
}
// 使用
//...
// 不要改变指针 p 指向的位置,不要执行 p = &a;
// 释放内存
free(p);
p = NULL;
//....
return 0;
}
#include
int main()
{
int a = 10;
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
p++;
//释放
free(p);
p = NULL;
return 0;
}
解释:
修改后:
#include
int main() {
int a = 10;
int* p = (int*)malloc(40);
if (p == NULL) {
return 1;
}
// 使用
p++; // 移动指针
// 重新指向起始位置
p--;
// 释放内存
free(p);
p = NULL;
return 0;
}
int main()
{
int a = 10;
int* p = (int*)malloc(40);
if (p == NULL)
{
return 1;
}
//使用
//释放
free(p);
p = NULL;
free(p);
p = NULL;
return 0;
}
修正这个问题的方法是只调用一次 free,而不是两次:
#include
int main() {
int a = 10;
int* p = (int*)malloc(40);
if (p == NULL) {
return 1;
}
// 使用
// 释放内存
free(p);
p = NULL;
// 避免再次释放相同的内存块
// free(p); // 这一行应该注释掉或删除
return 0;
}
void test()
{
int* p = (int*)malloc(100);
if (NULL != p)
{
*p = 20;
}
free(p);
p = NULL;
}
int main()
{
test();
//
while (1);
}
修改后:
void test()
{
int* p = (int*)malloc(100);
if (NULL != p)
{
*p = 20;
}
free(p);
p = NULL;
}
int main()
{
test();
return 0; // 添加这行以正常退出程序
}
忘记释放不再使用的动态开辟的空间会造成内存泄漏
切记:动态开辟的空间一定要释放,并且正确释放。
各位要对上面常见的动态内存开辟有一个清晰的认知,并避免这些问题的出现,今天的笔记到此结束啦