Здравствуйте, __GnoM, Вы писали:
А>>[ccode] А>>>class A А>>>{ А>>> public: А>>> A(); А>>> ~A(); А>>> BOOL Init(); А>>> BOOL Start(); А>>> . А>>> . А>>> . А>>> private: А>>> vector<B> vec; Элементы вектора хранятся по значению А>>>};
А>>>A::~A() А>>>{ А>>А> vector<B>::iterator iter = vec.begin(); // Этот код не может не падать. ВЕКТОР УДАЛИТ ЭЛЕМЕНТЫ САМ. А>>> while(iter != vec.end()) А>>> { А>>> delete iter; А>>> iter++; А>>> } А>>>}
__G>Можно уточнить, вектор удалит элементы сам путём вызова деструктора ~B() или как??? __G>Просто если в B имеет место динамическое выделение памяти, необходимо гарантировать её стопоцентное освобождение???
__G>Да и вопрос остался. Падает только на втором элементе вектора, первый успешно удаляется!
В vec элементы хранятся по значению, т.е. вектор сам их создает и уничтожает.
Поэтому руками удалять их _нельзя_, и этот while _нужно_ убрать. Иначе ошибка
будет возникать в деструкторе класса vector.
В вышепреведенном коде происходит следующее.
В векторе данные хранятся непрерывно одним блоком памяти. В используемой вами STL итератор
определен как указатель (в STLPort в отладочном режиме это не так, поэтому этот код c STLPort даже бы не скомпилировался).
В данном случае интератор, указывающий на начальный элемент вектора — это просто указатель
на блок памяти, выделенный классом vector. Поэтому первое удаление происходит нормально (да и то,
у других компиляторов здесь могла возникнуть ошибка из-за выделения по new[], а удалению по delete).
На следующей итерации итератор-указатель указывает на следующий элемент вектора, т.е. адрес
который находился внутри уже удаленного блока памяти.
Таким образом получается, что производится попытка освобождения памяти, начиная с адреса, с которого не выделялся ни один из блоков памяти, не говоря уже о том, что удаление блока памяти,
куда входил этот элемент вектора, уже произошло.
В результате — повреждение кучи с перспективой искать причины странных и непостоянно проявляющихся ошибок.
Можно сказать, что в данном случае вам еще повезло, что ошибка сразу возникает.
Так что либо в приведенном коде опечатки, либо автор кода не представляет,
что из себя представляет шаблонный класс вектора и как его можно использовать.
__G>Данный метод — это просто пример для обсуждения, в реально используемом классе нужно было гарантировать правильное создание объекта и инициализацию его параметров, поэтому создаётся динамически. Неудобно, но другого варинта не нашлось, пока....
Тогда лучше описать, какую задачу решаете по созданию объекта, может кто и лучше чего посоветует.