内存越界问题--C++

本文通过实例讲解了类中成员变量的空间部署原理,并详细分析了三种常见的内存管理问题:成员变量意外修改、数组下标越界及拷贝操作越界。提供了避免这些问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

某一天突然被问到一个问题:

怎么我的类成员变量在构造函数中明明已经初始化为零了,所有赋值的地方都断点了,也没有断点到被修改,怎么用它做判定条件的时候又有值了,而且有时候有,有时候正常

于是,讲解一下类中成员变量的空间部署:

一个类对象的地址就是类所包含的这一片内存空间的首地址,这个首地址也就对应具体某一个成员变量的地址。类的内存大小和其唯一的成员变量的内存大小是一致的(这个就是结构体一样的,类中有函数而已,但是类中的函数都是放在代码区,不影响其大小)

有了这个概念再来看一段代码

#include <iostream>

using namespace std;

int main()
{
	struct MyStruct
	{
		int num1[10];
		int sex;
	};

	MyStruct My;
	memset(&My, 0, sizeof(My));

	int num2[11] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2 };

	memcpy(My.num1, num2, sizeof(num2));

	cout << My.sex << endl;

	system("pause");
	return true;
}

!!!用结构体代替类了,从上面可以看出,定义的结构体My,

其大小 sizeof(My) = 44

定义的num2 = 44

所以将num2的大小拷贝到结构体My中,就会出现下图所示情况,没有给变量sex赋值,但是最后打印出来的值已经被改变。

 第二种情况、数组下标越界

很多情况,喜欢使用数组(数组小,下标方便)

int A[10] = {0};

void setAValue(int index,int t)
{
    A[index]=t;
}

setAValue(1,100);

setAValue(111,111);

如上图所示,就会出现数组下标越界问题。做好下标范围判断很有必要

三、拷贝越界(strncpy,memcpy等拷贝)

char A[32];
std::string Name = "";

//第一种,直接拷贝
strncpy(A,Name.c_str(),Name.size());

//这种情况会出现当Name长度很长的时候,赋值越界

所以我们在拷贝的时候,首先就是要考虑拷贝的内容和大小

#define LEN_NICKNAME 32

char A[LEN_NICKNAME];
std::string Name = "";

//第一种,直接拷贝
strncpy(A,Name.c_str(),Name.size());


//第二种判断长度后拷贝
if (Name.size() > LEN_NICKNAME - 1)
{
	auto str = Name[i].substr(0, LEN_NICKNAME - 1) + '\0';
	strncpy(A, str.c_str(), LEN_NICKNAME );

}
else
{
	strncpy(A, Name.c_str(), Name.size());
}

使用 strncpy 等安全函数时,当复制字符串到达指定的长度时,不会在目标字符串结尾添加 '\0' 字符,必须手工进行添加 '\0' 字符。当然,可以在申请内存时,将最后一个字节置为 '\0' 字符;也可以在调用 strncpy 函数后,紧接着赋 '\0' 字符。

 

暂时就是出现这么几个内存问题,后续遇到其他的问题再补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值