Windows VS/VSCode C++ delete[] char*类型报错问题——学习笔记

文章探讨了在C++中,strcpy函数可能导致内存溢出的情况,尤其是在向char数组写入超过其实际长度的字符串时。同时,文章解释了内存泄漏的原因,因为strcpy可能继续复制直到遇到空字符,即使超过了数组界限。开发者需要注意在Debug模式下的错误提示和潜在的内存管理问题。
摘要由CSDN通过智能技术生成

先说可能的情况:

  1. 向char* 多写入了超过其长度的字节。例如使用strcpy时,分配了n个元素,但源字符串长度也是n(实际复制时其实是n+1);
  2. 变量更改造成指针变换,如自加自减操作;
  3. 重复delete。

2,3都比较容易发现,一般不会错。
我们来看1。

引入

假设有以下代码片段:

char* a = new char[5];
strcpy(a,"AAAAA");
std::cout<<a<<std::endl;
delete[] a;

我的环境是Windows 11 + VSCode + gcc version 13.2.0 (x86_64-win32-seh-rev1, Built by MinGW-Builds project)以及VS2022。
以上这段代码编译能够通过,也能够执行。但在VS/VSCode的Debug模式下会报错。
VSCode会在strcpy处给出下划线并提示:

‘void* __builtin_memcpy(void*, const void*, long long unsigned int)’ writing 6 bytes into a region of size 5 overflows the destination [-Wstringop-overflow=]
向区域大小为5的区域写入6个字节会溢出目标

VS也会在执行时报错:
CRT检测到应用向对缓存末端后方写入
即:CRT检测到应用向对缓存末端后方写入
以上种种都说明我们向 a 中写入了超过5个字节。

原因

我们将目光投向 strcpy
strcpy简单复现一下是这样的:

char* strcpy(char* dst, char* src){
		char* ret = dest;
		while(*src != '\0'){
			*dst = *src;
			dst++;		//向后移一位
			src++;
		}
		*dst = *src;
		return ret;
	}

参考:https://blog.csdn.net/weixin_45031801/article/details/136616281

我们发现,在循环退出后,依旧有一行

	*dst = *src;

及:将源字符串末尾的 ‘\0’ 字符复制到目标字符串末尾,也就是说,我们末尾还需要有一位来存储结束符 ‘\0’。
其次,从上述代码来看,即便src长度超过dst,复制也不会停止,因此strcpy是能够将超过dst分配的内存的数据写入dst的。
再来看delete。

参考:https://blog.csdn.net/qq_45657288/article/details/114699235

个人理解如下,仅供参考:
new 分配了一块对应类型大小的内存并返回指向这块内存的指针;delete 则通过指针释放指针指向的被占用的一块块内存。
同理,new [] 分配了一串连续的内存,返回这些内存的头部指针,并记录内存的数量信息;delete[] 则通过头部指针与 new [] 记录的信息逐个删除分配的内存。

在开始的例子中,new char[5] 分配了五块内存用于存储5个char,但在strcpy中,我们将看似只有5个字符实际有6个字符的字符串 “AAAAA\0” 复制给了a,造成了a与实际大小不符的情况,而正是这种情况造成了内存泄漏。也正是因此才有了以上的报错。这种报错由于只出现在Debug中,如果直接生成运行而又没有发现可能造成很严重的内存泄漏。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值