You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

模拟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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 23:59:54