模拟C++ Vector机制时出现缓冲区溢出错误,求排查原因
问题分析与修正
你在手动实现类似vector的堆数组扩容机制时遇到了"Buffer overrun while writing to arr[0]"错误,核心问题出在数组长度计算错误和索引越界两个关键环节,具体分析和修正如下:
1. 致命错误:错误计算数组实际容量
代码中的int n = sizeof(arr[0]) / sizeof(int);完全错误。arr[0]是int*类型的指针,sizeof(arr[0])返回的是指针本身的内存大小(32位系统为4字节,64位系统为8字节),除以sizeof(int)(通常4字节)后,n的值永远是1或2,和你在堆上实际分配的数组大小(初始3,扩容后n+1)毫无关系。这直接导致:
- 初始数组明明有3个元素,你只会检查前1/2个位置是否为空
- 扩容逻辑基于错误的
n值执行,后续数组访问必然越界
解决方法:必须单独维护一个变量来记录当前数组的实际容量,不能通过指针的sizeof计算数组长度。
2. 索引越界:新元素写入位置错误
扩容后你创建了大小为n+1的新数组,数组的合法索引范围是0到n(数组下标从0开始),但代码中用了(arr[0])[n + 1] = e;,这明显超出了数组边界,直接触发缓冲区溢出错误。正确的写入位置应该是n(原数组有n个元素,新数组的第n位是第一个空位)。
修正后的完整代码
#include <iostream> using namespace std; int main() { cout << "We are trying to create Vector like mechanism.\n \n" << endl; int* arr[2]{ nullptr }; int capacity = 3; // 单独维护数组的实际容量 arr[0] = new int[capacity] {}; // 初始分配3个元素的堆数组 for (int i{1}; i > 0; i++) { char c1; cout << "Do you want to add elements : "; cin >> c1; if (c1 == 'y' || c1 == 'Y') { int e; bool a{false}; // 遍历整个数组寻找空位 for (int j{}; j < capacity; j++) { if ((arr[0])[j] == 0) { cout << "Enter the element to be entered : "; cin >> e; (arr[0])[j] = e; a = true; break; } } if (a == false) { // 执行扩容逻辑:原容量为capacity,扩容后为capacity+1 arr[1] = new int[capacity]; for (int k{}; k < capacity; k++) { (arr[1])[k] = (arr[0])[k]; } delete[] arr[0]; capacity += 1; // 更新数组容量 arr[0] = new int[capacity] {}; for (int l{}; l < capacity - 1; l++) { // 复制原数组的所有元素 (arr[0])[l] = (arr[1])[l]; } // 打印扩容后的数组 for (int t{}; t < capacity; t++) { cout << (arr[0])[t] << " "; } cout << endl; delete[] arr[1]; // 将新元素写入数组最后一个位置 cout << "Enter the element to be entered : "; cin >> e; (arr[0])[capacity - 1] = e; a = true; } } else if (c1 == 'n' || c1 == 'N') { cout << "OK, no new element was entered." << endl; break; } else { cout << "Enter a valid choice. ie.( Y/y for YES and N/n for NO)" << endl; } } delete[] arr[0]; if (arr[1] != nullptr) delete[] arr[1]; // 避免删除空指针 }
额外优化建议
- 可以新增
size变量记录已使用元素数量,无需每次遍历找0,提升效率 - 扩容时建议按倍数(比如2倍)扩容,减少内存分配的次数,这也是标准vector的扩容策略
- 保持对空指针的显式判断,代码鲁棒性更强
内容的提问来源于stack exchange,提问作者Viwhooo
相关产品推荐
相关产品推荐

