为何这段C++代码抛出写入访问违规异常?
解决写入访问违规:
v[i] = v[i - k]; 异常问题 首先,咱们直接揪出问题根源:你的eltolJobbra函数里只修改了数组长度n,但完全没给指针v重新分配足够的内存,再加上v可能本身就是未初始化的野指针,或者指向的内存已经失效,导致程序访问了不属于自己的内存区域,触发了写入访问违规。
错误原因拆解
- 你直接执行
this->n = this->n + k;把数组长度扩大了k,但原来的v指针指向的还是原来长度为n的内存块。当循环里访问v[i](i最大到n+k-1)时,已经超出了原内存块的范围,属于典型的数组越界访问。 - 错误提示里
this->v的值是0x443E112,这个地址看起来不是有效的堆内存地址(通常堆分配的地址会更大),说明v可能从未被正确初始化(比如默认构造函数里没把v设为nullptr或分配内存),或者之前的内存已经被释放了。
修复方案
要解决这个问题,核心是先为扩大后的数组重新分配内存,再移动原有元素,最后更新指针和长度。同时还要处理无效输入和内存分配失败的情况。
修改后的eltolJobbra函数
#include <stdexcept> // 用于bad_alloc异常 void NagyEgesz::eltolJobbra(int k) { // 处理无效输入:k为0或负数时不需要移动 if (k <= 0) { return; } // 为新数组分配内存,长度是原长度n + k int* ujV = new int[n + k]; if (!ujV) { // 内存分配失败时抛出异常 throw std::bad_alloc(); } // 将原有元素复制到新数组的第k个位置开始 for (int i = 0; i < n; ++i) { ujV[i + k] = v[i]; } // 填充前k个位置为0 for (int j = 0; j < k; ++j) { ujV[j] = 0; } // 释放原来的内存,避免内存泄漏 delete[] v; // 更新指针和数组长度 v = ujV; n = n + k; }
额外的必要检查
还要确保你的类的构造函数正确初始化v指针,彻底避免野指针问题:
默认构造函数
NagyEgesz::NagyEgesz() : v(nullptr), n(0), elojel(1) {}
带参数的构造函数
NagyEgesz::NagyEgesz(int elojel, int n, const int* szamjegyek) : elojel(elojel), n(n) { v = new int[n]; if (!v) { throw std::bad_alloc(); } // 复制传入的数字 for (int i = 0; i < n; ++i) { v[i] = szamjegyek[i]; } }
析构函数(必须添加,避免内存泄漏)
NagyEgesz::~NagyEgesz() { delete[] v; }
进阶补充:遵循Rule of Three
如果你的类需要被拷贝或赋值,还需要实现拷贝构造函数和赋值运算符重载,避免浅拷贝导致的重复释放内存问题:
// 拷贝构造函数 NagyEgesz::NagyEgesz(const NagyEgesz& masik) : elojel(masik.elojel), n(masik.n) { v = new int[n]; if (!v) { throw std::bad_alloc(); } for (int i = 0; i < n; ++i) { v[i] = masik.v[i]; } } // 赋值运算符重载 NagyEgesz& NagyEgesz::operator=(const NagyEgesz& masik) { if (this == &masik) { return *this; // 自赋值保护 } // 释放当前内存 delete[] v; // 分配新内存并复制数据 n = masik.n; elojel = masik.elojel; v = new int[n]; if (!v) { throw std::bad_alloc(); } for (int i = 0; i < n; ++i) { v[i] = masik.v[i]; } return *this; }
内容的提问来源于stack exchange,提问作者Mr.Robot
相关产品推荐
相关产品推荐

