IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 【C语言】动态内存的常见错误及面试题的讲解 -> 正文阅读

[C++知识库]【C语言】动态内存的常见错误及面试题的讲解

目录

一、

1.对NULL的指针的解引用操作

int main()
{
	int* p = (int*)malloc(20);
	*p = 5;
	return 0;

}

这个地方如果malloc开辟失败的话,p被赋为空指针,此时就出现了对空指针的解引用操作,这样是错误的。
所以在进行解引用之前应该加上一个判断。

int main()
{
	int* p = (int*)malloc(20);
	if (p == NULL)
	{
		return 1;
	}
	else
	*p = 5;
	return 0;

}

2.对动态开辟空间的越界访问

int main()
{
	int*p=(int*)malloc(20);
	if (p == NULL)
	{
		return 1;
	}
	int i = 0;
	for (; i < 20; i++)
	{
		*(p + i) = i;
	}
	free(p);
	p = NULL;
}

这里要注意20是20个字节,不是元素,只能访问5个int类型的元素,很容易就造成越界访问。

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

int main()
{
	int num = 10;
	int* p = &num;
	free(p);
	p = NULL;
	return 0;
}

这样就是错误的,free只能释放动态开辟内存的空间。

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

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
		return 1;
	int i = 0;
	for (; i < 5; i++)
	{
		*p = i;
		p++;
	}
	free(p);
	p = NULL;
			
	return 0;
}

在这里插入图片描述
在这里插入图片描述

所以如果要这样的话要先用另外一个指针来存放p。

5.对同一块动态内存多次释放

int main()
{
	int* p = (int*)malloc(40);
	if (p == NULL)
		return 1;
	int i = 0;
	for (; i < 5; i++)
	{
		*p = i;
		p++;
	}
	free(p);
	//........
	//........
	free(p);
	p = NULL;
			
	return 0;
}

1.在这里我们有可能在free之后没有把指针置为空指针,然后经过了一系列操作后又将该指针使用free释放。
2.如果我们在第一次free之后就将p置为空指针,后面的free接收一个空指针,是不会出现错误的。
3.这也告诉我们要在使用free之后,将该指针置为空指针。

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

int* get_mem()
{
	int* p = (int*)malloc(40);
	return p;
}
int main()
{
	int* ptr = get_mem();
	
	return 0;
}

当我们回到main函数中再继续操作时,很容易就忘记释放在get_mem函数中的动态开辟内存。只顾申请却忘了释放,这样就会导致内存泄漏。

二、面试题讲解

void GetMemory(char* p)
{
	p = (char*)malloc(100);
}

void Test(void)
{
	char* str = NULL;
	GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
}

int main()
{
	Test();
	return 0;
}

在这里插入图片描述

1.图中可以看出str还是NULL(并且出了GetMemory函数之后,创建的空间就被释放了,p所指向的地址无从查找。)
2.这里就出现了对空指针的解引用操作
3.没有对动态开辟内存释放
解决办法
1.对str传参进行传地址操作
2.return p;

void GetMemory(char** p)
{
	*p = (char*)malloc(100);
}

void Test(void)
{
	char* str = NULL;
	GetMemory(&str);
	strcpy(str, "hello world");
	printf(str);
	//释放
	free(str);
	str = NULL;
}
char* GetMemory(char* p)
{
	p = (char*)malloc(100);
	return p;
}

void Test(void)
{
	char* str = NULL;
	str = GetMemory(str);
	strcpy(str, "hello world");
	printf(str);
	free(str);
	str = NULL;
}

2.返回栈空间地址的问题

char* GetMemory(void)
{
	char p[] = "hello world";
	return p;
}

void Test(void)
{
	char* str = NULL;
	str = GetMemory();
	printf(str);
}
int main()
{
	Test();
	return 0;
}

在这里插入图片描述

所以当str再想去顺着地址寻找字符串的时候,就出错了。str此时是一个野指针。

void GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}

void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100);
	strcpy(str, "hello");
	printf(str);
}

int main()
{
	Test();
 //......
	return 0;
}

很明显应该在printf语句结束后,使用free来释放之前开辟的动态内存,否则会造成内存泄漏。之后还要将str置为NULL。

void Test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str);

	if (str != NULL)
	{
		//str是野指针,这里就是非法访问
		strcpy(str, "world");
		printf(str);
	}
}

1.free使用的位置不对,该动态内存后面还要继续使用
2.str判断是否为NULL(即malloc开辟空间是否成功)的位置不对,在判断之前就已经执行了strcpy。

正确的应该为

void Test(void)
{
	char* str = (char*)malloc(100);
	if (str == NULL)
		return;

	strcpy(str, "hello");
	free(str);
	str = NULL;

	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}

以上就是动态内存的常见错误,还有一些面试题的讲解,希望可以帮到大家,如有错误请指出。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 00:33:07  更:2022-09-30 00:35:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 4:48:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码