векторные итераторы несовместимы

У меня есть класс, в котором я хочу использовать большое количество векторов.

class Bar {
    Bar ();
    std::vector<Foo> * _grid;
    void someFunction ();
}

Bar::Bar () {
    _grid = (std::vector<Foo> *)malloc(_gridSize * sizeof(std::vector<Foo>);
    memset(_grid, 0, _gridSize * sizeof(std::vector<Foo>);
}

void Bar::someFunction () {
    int index = 0;
    std::vector<Foo> someVariable = _grid[index];
}

Однако, как только я вызываю someFunction(), я получаю сообщение об ошибке vector iterators incompatible, как только в _grid[index] есть какой-то контент. Если вектор пустой, он работает.

Я читал о сообщении об ошибке, создаваемом недействительными итераторами, однако, поскольку я ничего не меняю в векторах на данный момент, я не понимаю, что здесь не так.


person Etan    schedule 08.12.2010    source источник
comment
Почему вы используете malloc? Ваш вектор не строится!   -  person Fred Larson    schedule 08.12.2010
comment
Странно было то, что push_back и т. д. работали, и визуальная студия правильно показала это с емкостью и размером ^^. Забыл конструктор.   -  person Etan    schedule 08.12.2010
comment
У меня есть класс, в котором я хочу использовать большое количество векторов. Какую сумму вы, по-видимому, определяете во время выполнения. Э-э... почему бы просто не использовать вектор векторов? Вы как-то забыли, для чего для используются векторы? :)   -  person Karl Knechtel    schedule 08.12.2010
comment
Что касается того, почему это работает, вам повезло, что memset просто произошло сделать что-то достаточно близкое к тому, что нужно для вашей конкретной реализации std::vector, чтобы обмануть ваш отладчик. Пожалуйста, никогда не используйте эту функцию в C++. Даже если вы просто хотите обнулить массив из char с. В современном C++ нужная вам функциональность пишется как std::fill и живет в <algorithm>. Хотя это для общего случая; вы можете вызывать конструкторы, просто используя конструктор для вектора векторов или его функцию-член .resize().   -  person Karl Knechtel    schedule 08.12.2010
comment
Ах, проблема с векторами векторов и последующим вызовом изменения размера заключается в том, что это занимает около 10 секунд, так как у меня около 100 тысяч векторов. @Karl: Именно это смутило меня и сбило с толку от простой вещи, которой не хватало конструктору. Объедините это с результатами Google об аннулировании итератора, и вы получите мою проблему ;-) Все указывало на очевидное решение.   -  person Etan    schedule 08.12.2010
comment
... и сколько Foo у вас есть для начала в каждом векторе? Вы хотите, чтобы хранилище оставалось прямоугольным, т.е. каждый вектор имел одинаковую длину? Что вы на самом деле пытаетесь сделать?   -  person Karl Knechtel    schedule 08.12.2010
comment
У меня есть несколько точек в 3D-пространстве, которые я хочу поместить в воксели. Поскольку я не могу использовать предопределенную сетку, я использую бесконечную сетку и некоторую хеш-таблицу, в которую каждая позиция отображается. Таким образом, все точки одного и того же вокселя оказываются в одном сегменте. Сетка — это именно эта хеш-таблица. Не каждый вектор имеет одинаковую длину.   -  person Etan    schedule 08.12.2010


Ответы (1)


Вы почти наверняка не хотите динамически выделять вектор; просто включите его как член класса:

class Bar { 
    std::vector<Foo> _grid;
};

Если вы действительно хотите динамически выделить вектор, вы хотите использовать new, который строит вектор. Как сейчас написано, вы выделяете malloc места для вектора и устанавливаете все байты, занимаемые вектором, равными нулю. Вы никогда не вызываете конструктор std::vector для выделенного объекта, поэтому вы не можете использовать его как std::vector.

Убедитесь, что у вас есть хорошая вводная книга по C++, из которой можно изучить язык. Если вы не понимаете модель памяти C++ и объектную модель, теперь вы сможете написать правильный код C++.

person James McNellis    schedule 08.12.2010
comment
Ну и хочу :-) Так как индекс в сетке не должен со временем меняться. - person Etan; 08.12.2010
comment
Ваша подсказка с взятием нового помогла решить мою проблему. Благодарю. - person Etan; 08.12.2010
comment
@Etan: Ваш комментарий не имеет смысла. Адрес вектора не изменится, пока существует экземпляр Bar, членом которого он является. - person James McNellis; 08.12.2010
comment
Это массив фиксированного размера векторов Foos. - person Etan; 08.12.2010
comment
Если это фиксированный размер, то почему вы выделяете его динамически? - person Karl Knechtel; 08.12.2010
comment
потому что размер определяется во время выполнения, а затем фиксируется для остальной части выполнения. Здесь подойдет vector<vector<Foo> >, но в моем случае это занимает слишком много времени. - person Etan; 08.12.2010
comment
@Etan: Что значит занимает слишком много времени? - person James McNellis; 08.12.2010
comment
это похоже на stackoverflow.com /вопросы/1606894/ - person Etan; 08.12.2010