如果我不使用vector.reserve(),为什么我的指针会失效?

时间:2017-03-06 18:00:11

标签: c++ pointers memory vector

我有一小段代码,它包含一个用于二维顶点的类(Vector2)向量和一个模板类DynamicLine的向量,它将Vector2类型对象作为参数。

std::vector<Vector2> m_coords;
std::vector<DynamicLine<Vector2>> m_lines;
Vector2 *lineVec = NULL;





 bool draw = true;
 case DrawingWidgetState::ADD_VERTEX_SELECTED:{
                for(auto it = m_coords.begin(); it != m_coords.end(); it++)
                     if(it->distanceFrom(Vector2(event->x(), event->y())) < 20 && !m_coords.empty()){
                        draw = false;
                        break;
                     }

                if(draw){

                    if(event->x() < m_mainWindow->width() - 10 && event->x() >= 10
                            && event->y() < m_mainWindow->height() && event->y() >= 10) {


                        m_coords.push_back(Vector2(event->x(), event->y()));
                        update();
                    }
                }
                break;

            }


case DrawingWidgetState::ADD_LINE_SELECTED:{
                for(auto it = m_coords.begin(); it != m_coords.end(); it++)
                    if(it->distanceFrom(Vector2(event->x(), event->y())) < 10){

                        if(!i){
                            lineVec = &(*it);
                            i++;
                        }

                        else{

                            m_lines.push_back(DynamicLine<Vector2>(lineVec, &(*it)));
                            i = 0;

                        }
                        update();
                        break;
                    }
                break;

            }

接下来是问题。例如,如果我在它们之间添加两个顶点和一条线,那么一切正常。但是,如果我现在添加另一个顶点(m_coords.push_back(Vector2(event-&gt; x(),event-&gt; y()));)那么m_lines向量中的行dissaperas和值将更改为非常随机的大数字。我读了一些关于指针失效的内容。如果将新值推送到vector,那么最终会扩展一些值。我还使用vector :: reserve修复了我的问题,但是因为我确定我没有做到这一点,任何人都可以解释一下我应该如何使用vector :: reserve以及为什么我需要这样做?

2 个答案:

答案 0 :(得分:1)

我没有密切关注你的代码,但似乎是导致你麻烦的向量重新分配。

矢量始终跟踪两种尺寸:容量和它包含的对象数量。如果你做了push_back,并且它的容量已经达到最大值,它会将自身复制到内存中的另一个位置,空间更大,容量更大。你的指针可能仍然指向原始位置。

使用向量时,最好保留索引而不是指针。

编辑:迭代可以执行插入操作的数组。那不应该。

答案 1 :(得分:1)

这很简单。当push_backvector没有足够capacity时,它需要分配更多内存并将元素复制(或移动)到新位置。这会使指向旧元素的任何迭代器/指针无效(它们现在只是指向旧的释放内存块),这意味着它们基本上指向垃圾 - 所以你必须在push_back之后获得新的迭代器。

调用reserve告诉向量预先分配一块内存,以便保证任何后续 push_back不需要重新分配(如果你留在保留(实际上是capacity))因此不会使元素的迭代器/指针无效。