У меня есть два класса, похожие на это:
class A
{
public:
B* ptr1;
}
class B
{
public:
std::vector<A*> list;
}
В основной реализации я делаю что-то вроде этого:
int main() {
// there are a lot more A objects than B objects, i.e. listOfA.size() >>> listOfB.size()
std::vector<A> listOfA;
std::vector<B> listOfB;
while (//some loop)
{
listOfB[jj].list.push_back( &(listofA[ii]) );
listOfA[ii].ptr1 = &( listOfB[jj] );
}
} // int main end
В основном что-то вроде этого. Многие объекты A назначаются одному объекту B, и эти объекты A хранятся в этом векторе указателей как указатели. Кроме того, каждый из этих объектов A получает указатель на объект B, которому они принадлежат. Для контекста я в основном использую алгоритм подключенных компонентов с кодированием длин серий (для сегментации изображения), где класс A — это линейные сегменты, а класс B — конечные объекты на изображении.
Таким образом, все указатели вектора в классе B указывают на объекты, которые хранятся в обычном векторе. Эти объекты должны быть удалены, когда обычный вектор выходит за рамки, верно? Я читал, что вектор указателя, как в классе B, обычно требует написания ручного деструктора, но я думаю, что здесь этого быть не должно...
Причина, по которой я спрашиваю, конечно же, потому что мой код продолжает падать. Я использую камеру Asus Xtion Pro для получения изображений, а затем выполняю алгоритм для каждого изображения. Странно то, что программа вылетает всякий раз, когда я чуть сильнее встряхиваю камеру. Когда камера неподвижна или перемещается незначительно или медленно, ничего не происходит. Также при использовании другого алгоритма (тоже связанные компоненты, но без run-length-encoding и тоже не использующего указатели) ничего не вылетает, сколько бы я не тряс камеру. Кроме того, в режиме отладки (который работал намного медленнее, чем в режиме выпуска) тоже ничего не зависало.
Я попытался создать деструктор для вектора указателя в классе B, но это привело к ошибке «блок действителен», поэтому я предполагаю, что он удалил что-то дважды. Я также пытался заменить каждый указатель на С++ 11 std::shared_ptr, но это приводило только к очень нерегулярному поведению, и код все еще зависал, когда я встряхивал камеру.
В основном я просто хочу знать, выглядит ли приведенный выше код с точки зрения утечки памяти и обработки указателей нормально или в коде есть ошибки, которые могут привести к сбоям.
РЕДАКТИРОВАНИЕ (РЕШЕНО): Решение (см. принятый ответ) состояло в том, чтобы гарантировать, что размер вектора listOfB не изменится во время выполнения, например, с помощью резервирования () для резервирования достаточно места для него. После этого все заработало нормально! По-видимому, это сработало, потому что, если размер вектора 'listOfB' изменяется (с помощью push_back()), адреса внутренней памяти экземпляров B в нем также изменяются, в результате чего указатели в экземплярах A (которые указывают на экземпляры B) теперь указать неправильные адреса - и тем самым привести к проблемам, которые приводят к сбою.
По поводу дрожания камеры: по-видимому, тряска камеры приводила к очень размытым изображениям с большим количеством элементов для сегментации, что увеличивало количество объектов (т. е. приводило к увеличению размера, необходимого для listOfB). Итак, тайна раскрыта! Большое спасибо! :-)