C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍

news2024/11/27 11:40:01

文章目录

  • 前言
  • 一、常见的动态内存错误
    • 1. 对NULL指针的解引用操作
    • 2. 对动态开辟空间的越界访问
    • 3. 对非动态开辟内存使用free()
    • 4. 使用free释放一块动态开辟内存的一部分
    • 5. 对同一块动态内存多次释放
    • 6. 动态开辟内存忘记释放(内存泄漏)
  • 二、几个经典笔试题
    • 1.
    • 2.
    • 3.
    • 4.
  • 三、 c/c++内存开辟空间图
  • 总结


前言

C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍


一、常见的动态内存错误

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

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int* p = (int*)malloc(40);

	// 没有对malloc开辟失败的拦截,所以p有可能为空指针
	// 程序可能崩溃
	*p = 20;

	return 0;
}

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	int* p = (int*)malloc(40);

	if (NULL == p)
	{
		printf("%s\n", strerror(errno));
	}
	
	int i = 0;
	for (i = 0; i <= 10; i++) // 动态内存越界访问,程序报错
	{
		*(p + i) = i;
	}

	free(p);
	p = NULL;

	return 0;
}

3. 对非动态开辟内存使用free()

#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a = 0;
	int* p = &a;

	free(p);
	p = NULL;

	return 0;
}

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	int* p =(int*)malloc(40);

	if (NULL == p)
	{
		printf("%s\n", strerror(errno));
	}

	int i = 0;
	for (i = 0; i < 5; i++)
	{
		*p = i;
		p++; // p 的地址一直在改变,free(p)没有指向动态内存的起始地址
		// 程序崩溃
	}

	free(p);
	p = NULL;

	return 0;
}

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	int* p = (int*)malloc(40);
	
	// ....
	free(p); // 释放了一次,但是p没有置为空指针
	// 此时p为野指针

	// p = NULL;

	// .....
	free(p); // 此时程序报错,p是野指针

	return 0;
}

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void test()
{
	int* p = (int*)malloc(40);

	if (NULL == p)
	{
		printf("%s\n", strerror(errno));
		return;
	}

	int flag = 0;
	scanf("%d", &flag);

	if (flag == 5)
	{
		return;
	}
	
	free(p);
	p = NULL;
}

int main()
{
	test();
	return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int* test()
{
	int* p = (int*)malloc(40);

	if (NULL == p)
	{
		return p;
	}
	return p;

}

int main()
{
	// test 函数开辟空间
	int* ret = test();
	// 忘记释放
	return 0;
}
所以,动态开辟的空间一定要释放,并且要正确释放。

二、几个经典笔试题

1.

char* str = "hello world";
printf(“%s\n”, str); // hello world
printf(“hello world”\n); // hello world
printf(str) // hello world
str 存放 h 的地址, 所以 printf(""hello world); 和 printf(str);是一样的效果

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char* p)
{
	p = (char*)malloc(100);
	// 出了GetMemory函数 p会被销毁
	// 无法再找到 动态内存,所以内存泄漏
}

void Test(void)
{
	char* str = NULL;
	GetMemory(str);
	// str 是空指针,解引用时,程序崩溃
	strcpy(str, "hello world");
	printf(str);
}

int main()
{
	Test();

	return 0;
}
  1. 修改1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char** p)
{
	*p = (char*)malloc(100);
	// *p 指向str,str被赋值为动态内存的地址
}

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

int main()
{
	Test();

	return 0;
}
  1. 修改2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* GetMemory()
{
	char* p = (char*)malloc(100);
	// *p 指向str,str被赋值为动态内存的地址
	return p;
}

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

int main()
{
	Test();

	return 0;
}

2.

#include <stdio.h>
#include <string.h>
char* GetMemory(void)
{
	char p[] = "hello world";
	return p; // 出了 函数 ,p[] 就会被销毁
	// 所以str 接收到了地址,但是p[]的内容被销毁, 无法被找到
}
void Test(void)
{
	char* str = NULL;
	str = GetMemory(); // str 是一个野指针
	printf(str); // 烫烫烫烫烫烫烫烫x魪?
}

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

3.


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char* GetMemory(char** p, int num)
{
	*p = (char*)malloc(num);
}
void Test(void)
{
	char* str = NULL;
	GetMemory(&str, 100); 
	strcpy(str, "hello");
	printf(str);  // hello
	// 但是没有释放内存空间
	// 可以如下释放
	 /*free(str);
	 str = NULL;*/
}

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

4.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void Test(void)
{
	char* str = (char*)malloc(100);
	strcpy(str, "hello");
	free(str); // 释放空间,str变成野指针
	if (str != NULL)
	{
		strcpy(str, "world");
		printf(str);
	}
}

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

三、 c/c++内存开辟空间图

在这里插入图片描述


总结

C语言常见的动态内存错误及几个经典笔试题以及c/c++内存开辟空间等的介绍

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1650562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【busybox记录】【shell指令】shuf

目录 内容来源&#xff1a; 【GUN】【shuf】指令介绍 【busybox】【shuf】指令介绍 【linux】【shuf】指令介绍 使用示例&#xff1a; 打乱内容 - 默认输出 打乱内容 - 最多输出n行 打乱内容 - 将输出写入文件 打乱内容 - 重复输出 打乱内容 - 打乱本条指令的参数 打…

Concise CoT(CCoT)提示词工程

原文地址&#xff1a;concise-chain-of-thought-ccot-prompting 2024 年 1 月 24 日 传统的 CoT 是以增加输出令牌使用为代价的&#xff0c;CCoT 提示是一种提示工程技术&#xff0c;旨在减少 LLM 响应的冗长和推理时间。 基于LLMs的生成式人工智能应用程序必须使用多管齐下的方…

静态分配IP,解决本地连接不上Linux虚拟机的问题

在Window环境下&#xff0c;使用远程终端工具连接不了VMware搭建的Linux虚拟机&#xff08;CentOS 7&#xff09;&#xff0c;并且在命令行ping不通该Linux虚拟机的IP地址。下面通过配置网关解决本地与Linux虚拟机连接问题&#xff1a; 1 查看虚拟机网关地址 在VMware虚拟机上…

文本清洁器:如何一键批量删除空格,让内容更整洁的技巧

在日常工作和学习中&#xff0c;我们经常需要处理大量的文本内容。而文本中多余的空格往往会让内容显得杂乱无章&#xff0c;影响阅读体验。为了解决这个问题&#xff0c;我们可以使用办公提效工具来一键批量删除空格&#xff0c;让内容更加整洁易读。 一、为什么需要批量删除空…

js宏任务微任务输出解析

第一种情况 setTimeout(function () {console.log(setTimeout 1) //11 宏任务new Promise(function (resolve) {console.log(promise 1) //12 同步函数resolve()}).then(function () {console.log(promise then) //13 微任务})})async function async1() {console.log(async1 s…

AI模型:windows本地运行下载安装ollama运行Google CodeGemma可离线运行数据模型【自留记录】

AI模型&#xff1a;windows本地运行下载安装ollama运行Google CodeGemma可离线运行数据模型【自留记录】 CodeGemma 没法直接运行&#xff0c;需要中间软件。下载安装ollama后&#xff0c;使用ollama运行CodeGemma。 类似 前端本地需要安装 node.js 才可能跑vue、react项目 1…

华为:三层交换机与路由器连通上网实验

三层交换机是一种网络交换机&#xff0c;可以实现基于IP地址的高效数据转发和路由功能&#xff0c;通常用于大型企业、数据中心和校园网络等场景。此外&#xff0c;三层交换机还支持多种路由协议&#xff08;如OSPF、BGP等&#xff09;&#xff0c;以实现更为复杂的网络拓扑结构…

Java数据结构---链表

目录 链表的基本概念 LinkedList ArrayList和LinkedList的区别 链表的基本概念 当在ArrayList任意位置插入或删除元素时&#xff0c;就需要将后续元素整体往前或者整体往后搬移&#xff0c;时间复杂度O&#xff08;n&#xff09;&#xff0c;效率比较低&#xff0c;因此Arra…

【计算机科学速成课】笔记三

文章目录 17.集成电路真空管时代晶体管时代集成电路时代印刷电路板时代光刻时代 17.集成电路 Over the past six episodes, we delved into software, 过去 6 集我们聊了软件 \N 从早期编程方式到现代软件工程 from early programming efforts to modern software engineerin…

每天五分钟计算机视觉:通过交并比判断对象检测算法的性能

本文重点 在对象检测领域,交并比(Intersection over Union,简称IoU)是衡量算法性能的重要指标之一。它不仅直观地反映了预测框与真实框之间的重叠程度,还是判断算法是否“运行良好”的关键依据。 那个定位是好的? 对象检测任务中,我们希望不仅检测到对象,同时我们还希…

分析错误ValueError: could not determine the shape of object type ‘Series‘

这个错误提示 ValueError: could not determine the shape of object type Series 通常发生在尝试将 pandas 的 Series 直接转换为 PyTorch 的 tensor 时&#xff0c;尤其是当 Series 的数据类型不明确或者包含非数值类型的数据时。为了修正这个问题&#xff0c;确保在转换之前…

每日两题 / 138. 随机链表的复制 148. 排序链表(LeetCode热题100)

138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 用哈希表记录原链表中的节点是否被复制过 遍历原链表并通过哈希表维护新链表 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node(int _val) {val _val;next NULL;rand…

反汇编一个ARM64的机器码

文章目录 使用objdump直接阅读ARM64手册使用反汇编网站 有下面一个机器码&#xff1a;0x929ffee9&#xff0c;如何翻译成汇编呢&#xff1f; 下面介绍几种做法&#xff1a; 使用objdump 将这个机器码写到文件中&#xff0c;然后使用objdump去反汇编 创建一个二进制文件 dd…

特斯拉擎天柱已经进厂拣电池了,其他“机器打工人”赶得上吗? | 最新快讯

文陈斯达 编辑李然 5 月 6 日消息&#xff0c;特斯拉放出了他们的人形机器人——擎天柱&#xff08;Optimus&#xff09;的最新演示视频。 特斯拉的工厂中&#xff0c;擎天柱机器人经过数据训练&#xff0c;可以轻巧自由地拿取电池&#xff0c;放进电池槽中排列整齐。 来源&…

error: pathspec ‘XXX‘ did not match any file(s) known to git

使用vscode&#xff0c;在本地开发切换分支时&#xff0c;报以下错误&#xff1a; error: pathspec XXX did not match any file(s) known to git 该问题是由于没有对应分支的原因。 首先使用一下命令&#xff0c;查看本地及远程的所有分支。 git branch -a 若没有对应的分…

【练习2】

1.汽水瓶 ps:注意涉及多个输入&#xff0c;我就说怎么老不对&#xff0c;无语~ #include <cmath> #include <iostream> using namespace std;int main() {int n;int num,flag,kp,temp;while (cin>>n) {flag1;num0;temp0;kpn;while (flag1) {if(kp<2){if(…

FPGA学习笔记(3)——正点原子ZYNQ7000简介

1 ZYNQ-7000简介 ZYNQ 是由两个主要部分组成的&#xff1a;一个由双核 ARM Cortex-A9 为核心构成的处理系统&#xff08;PS&#xff0c;Processing System&#xff09;&#xff0c;和一个等价于一片 FPGA 的可编程逻辑&#xff08;PL&#xff0c;Programmable Logic&#xff0…

数据结构(c):队列

目录 &#x1f37a;0.前言 1.什么是队列 2. 队列的实现 2.1定义队列节点 2.2定义队列 2.3队尾入队列 2.4判断队列是否为空 2.5队头出队列 2.6 队列首元素 2.7队尾元素 2.8队列内的元素个数 2.9销毁队列 3.试运行 &#x1f48e;4.结束语 &#x1f37a;0.前言 言C之…

HTML_CSS学习:尚硅谷——尚品汇

一、index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>荣耀</title> <!-- 引入页签图标--><link rel"shortcut icon" href"./HONOR%20.ico" type&qu…

LeetCode:滑动窗口最大值

文章收录于LeetCode专栏 LeetCode地址 滑动窗口最大值 题目 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。   返回 滑动窗口中的最大值 。   示例 1…