常见的动态内存错误

举报
念君思宁 发表于 2023/02/10 20:22:55 2023/02/10
【摘要】 常见的动态内存错误

常见的动态内存错误有很多,笔者仅仅举出几个典型的列子,供大家参考一下!!

1.对NULL(空指针)进行解引用操作!!

请看代码:

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
	int* p = (int*)malloc(20);
	*p = 5;
	return 0;
}

显而易见的,这段代码是错误的!!没有对malloc函数,开辟内存空间失败后的判断!!

malloc函数开辟了20个字节的空间,将p指向这20个字节,p指向这20个字节的起始位置,而p作为整型指针,对其解引用,访问4个字节!将5赋值给*p,则第一个元素为5!但是,代码看着虽好,但是却显得不少很严谨!!原因在于:malloc函数的返回值不确定是否为:NULL(空指针),当malloc开辟空间失败,会返回NULL(空指针),而对空指针解引用,会出现错误!!

下面请看正确的书写代码格式:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
	int* p = (int*)malloc(20);
	if (*p == NULL)
	{
		//如果p为NULL(空指针)将进行怎样的操作??
		perror("malloc");
		return 1;
	}
	else
	{
		*p = 5;
	}
	free(p);
	p = NULL;
 
	return 0;
}
 

在上述的正确代码中,具体内容的变化,我们可以通过调试可以看出来!!在此,笔者就先不做过多的解析!!

2.对动态内存开辟的越界访问

请看笔者的代码:

#include <stdio.h>
#include <stdlib.h>
 
int main()
{
	int* p = (int*)malloc(20);
	if (p == NULL)
	{
		return 1;
	}
	//使用
	int i = 0;
	for (i = 0; i < 20; i++)
	{
		*(p + i) = i;
	}
 
	//打印
	for (i = 0; i < 5; i++)
	{
		printf("%d ", *(p + i));
	}
	//释放
	free(p);
	p = NULL;
	return 0;
}

在上述的代码中:malloc函数开辟了20个字节,用来存放5个整型,但是,在for循环里面,进行了越界访问!所以,导致程序崩溃!!

 

 3.对非动态开辟的内存,使用free释放

int main()
{
	int num = 10;
	int* p = &num;
 
	//……代码的其他内容!
 
	//释放
	free(p);
	p = NULL;
}

在上述代码中:int num = 10;  是一个局部变量,进入这个程序的时候开始创建,出这个程序的时候,就进行销毁,不需要进行free释放!

在该段代码的最后:用free来释放,会导致程序的崩溃!!

 4.使用free释放一块动态开辟内存的一部分

请看笔者的代码:

 
#include <stdio.h>
#include <stdlib.h>
 
int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
		return 1;
	}
	int i = 0;
	for (i = 0; i < 5; i++)
	{
		*p = i;
		p++;
	}
	//释放
	free(p);
	p = NULL;
}

上述代码,也会导致程序崩溃!!

首先,开辟了40个字节,Int 类型,可以存放10给整型数据,但是,在for循环中,由于 for (i = 0; i < 5; i++);使用了5个!!,随着p++的进行,此时,p已经指向第五个元素的位置,不再是指向起始位置了!!

 但是,在free(p)的释放中,也释放不了后面的空间,导致程序崩溃!!!

在free释放的时候,p指向的不再是,动态内存开辟的起始位置了!!因此需要用另外一个指针来遍历!!

总结:对于动态内存开辟的空间,一定要记录其起始位置,若没有记录起始位置,一直进行++(往后走),最终会导致这片空间无法释放!!

5.动态开辟内存忘记释放(内存泄漏)

请看笔者的代码:

 
#include <stdio.h>
#include <stdlib.h>
 
int* get_memory()
{
	int* p = (int*)malloc(40);
	//其他使用代码!!
 
	return p;  //返回动态内存空间的起始地址!!
}
 
int main()
{
	int* ptr = get_memory();
 
	//使用
 
	//…………其他代码
 
	//忘记释放了!!
 
	return 0;
}

在函数体的部分:    return p的作用: 是返回动态内存空间的起始地址!!

但是在最后没有进行free所以,出现了错误!!

正确的free代码为:


  1. free(ptr);

  2. ptr = NULL;

在这里,释放的是:ptr所指向的空间!!

忘记释放不再使用的动态开辟的空间,会造成内存泄漏!!切记,动态开辟的空间,一定要释放,并且正确释放!!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。