C++ 空vector执行reserve后使用下标直接对元素赋值的问题

问题遇到的现象和发生背景

首先定义一个空容器,然后使用reserve接口给容器申请一段空间。再通过for循环和x[i] = i;的方式对各个元素赋值,如此一来。x.begin()和x.end()相等,同时size也是0。如果使用x.at()或其他一些会判断越界的接口,再执行时会抛出越界异常。

我的解答思路和尝试过的方法

我觉得迭代器是和size保持一致的,如果初始化给定长度,则size和迭代器都会正常。但是如果只使用reserve和非push/insert进行赋值时,就出现不匹配的情况了。
我知道这种操作不合法,但是能不能从vector的角度解释一下这样的和容器设计的角度有什么冲突?

不对,第一步就有问题,使用reverse,然后使用for循环赋值。这一步就崩溃了。因为reverse是为容器预留空间

vector 的reserve增加了vector的capacity,但是它的size没有改变!而resize才是改变了vector的capacity同时也增加了它的size!
原因如下: reserve是容器预留空间,但在空间内不真正创建元素对象,所以在没有添加新的对象之前,不能引用容器内的元素。加入新的元素时,要调用push_back()/insert()函数。
正是由于不断的push_back会进行内存的重新自动分配的问题
为了避免重新分配内存带来的问题,vector提供了reserve函数。
reserve的作用是更改vector的容量(capacity),使vector至少可以容纳n个元素。
如果n大于vector当前的容量,reserve会对vector进行扩容。

例如,假定你想建立一个容纳1-1000值的vector。没有使用reserve,你可以像这样来做:

vector v; for (int i = 1; i <= 1000; ++i) v.push_back(i);

在大多数STL实现中,这段代码在循环过程中将会导致2到10次重新分配。

把代码改为使用reserve,我们得到这个:

vector v; v.reserve(1000); for (int i = 1; i <= 1000; ++i) v.push_back(i);

这在循环中不会发生重新分配。

没太理解你说的情况,能用一段代码,来描述吗?

vector<vector<POINT2D>>  triangles; //三角形集合  平面
    //vector<vector<POINT3D>>     triangles2;    //立体
    triangles.reserve(width*height*2);
    //(1)形貌层的三角化
    for (int ny = 0; ny < height - 1; ny++)
    {
        vector<POINT2D> triPoints;
        triPoints.reserve(4);
        for (int nx = 0; nx < width - 1; nx++)
        {
            BOOL bMaskX0Y0 = MASK(nx, ny);
            BOOL bMaskX1Y0 = MASK(nx + 1, ny);
            BOOL bMaskX0Y1 = MASK(nx, ny + 1);
            BOOL bMaskX1Y1 = MASK(nx + 1, ny + 1);
            triPoints.clear();
            if (bMaskX0Y0 && bMaskX1Y0 && bMaskX0Y1)
            {
                //顺时针方向  下三角形
                triPoints[0].x = nx;
                triPoints[0].y = ny;
                triPoints[1].x = nx;
                triPoints[1].y = ny + 1;
                triPoints[2].x = nx + 1;
                triPoints[2].y = ny;
                triangles.push_back(triPoints);
            }
            triPoints.clear();
            if (bMaskX1Y0 && bMaskX0Y1 && bMaskX1Y1)
            {
                //顺时针方向  上三角形
                /*triPoints[0].x = nx;
                triPoints[0].y = ny + 1;
                triPoints[1].x = nx + 1;
                triPoints[1].y = ny + 1;
                triPoints[2].x = nx + 1;
                triPoints[2].y = ny;*/
                POINT2D pt;
                pt.x = nx; pt.y = ny + 1; triPoints.push_back(pt);
                pt.x = nx + 1; pt.y = ny + 1; triPoints.push_back(pt);
                pt.x = nx + 1; pt.y = ny; triPoints.push_back(pt);
                triangles.push_back(triPoints);
            }
        }
    }

遇到了同样的问题,上面这段代码 调试的结果是。

img

img

size为0,导致我用下标取值的时候直接崩溃。