Конкретным источником вашей проблемы являются следующие строки:
objects_copy.push_back(objects[ rand() % x ]);
objects_copy[q].Reset();
Проблема в том, что когда вы пытаетесь вставить копии объектов в objects_copy
, вы в конечном итоге делаете мелкую копию объектовв objects
vector
.Это означает, что объекты в двух векторах будут иметь указатели, которые являются копиями друг друга.Следовательно, когда вы вызываете Reset
для элементов objects_copy
vector
, вы освобождаете память, на которую все еще указывают элементы массива objects
.
Проблема в том, что вашc_A
класс нарушает правило трех .Поскольку ваш класс инкапсулирует ресурс, он должен иметь деструктор, конструктор копирования и оператор присваивания копии.Если вы определите эти три функции, то при попытке скопировать объекты в objects_copy
vector
у вас будет возможность управлять базовым ресурсом, возможно, путем дублирования или подсчета ссылок.Для получения подробной информации о том, как написать эти функции, посмотрите это описание о том, как написать эти функции.
EDIT : вот более подробное описание того, что происходит:
Проблема в том, что когда вы добавляете объект в vector
, вы фактически не сохраняете этот объект в vector
.Скорее, вы храните копию этого объекта.Таким образом, когда вы пишете objects_copy.push_back(objects[ rand() % x ]);
, вы не сохраняете один и тот же объект в обоих vectors
.Вместо этого вы создаете копию одного из объектов из objects
и сохраняете ее в objects_copy
.Так как ваш тип c_A
не имеет определенных функций копирования, это приводит к созданию мелкой копии объекта, которая создает копию указателя.Это означает, что если вы думаете об исходном объекте из списка objects
и его соответствующей копии в objects_copy
, у каждого из них будет копия одного и того же указателя p_struct
.Когда вы вызываете Reset
для объекта в objects_copy
vector
, вы освобождаете память, на которую указывает указатель.Однако вы не обновили указатель исходного объекта, хранящегося в objects
, и теперь этот указатель ссылается на мусорную память.Попытка использовать этот указатель приводит к неопределенному поведению, что приводит к сбою.
Добавление функций копирования исправит это, позволив вам контролировать процесс создания копии.Если вы определяете функцию копирования для c_A
, которая заставляет копию указывать на новую копию объекта, на которую указывает оригинал, эта проблема не возникнет, поскольку у каждого объекта будет свой собственный отдельный указатель.Кроме того, если вы используете подсчет ссылок, то вы можете избежать проблемы, не удаляя ресурс, если знаете, что на него указывает какой-то другой объект.
Надеюсь, это поможет!