Есть ли способ сохранить блок памяти для контейнера? - PullRequest
0 голосов
/ 15 сентября 2011

Надеюсь, я проясню ....

В моем коде я определяю box, который содержит набор элементов (bead):

vector<vector<vector<set<std::tr1::shared_ptr<bead> > > > > boxes;

Я добавляю элемент к box, используя:

boxes[i][j][k].insert(aBead);

По какой-то причине я получаю ошибку сегментации здесь.Насколько я могу судить, ошибка сегментации не возникает из-за недопустимых bead и i, j, k, все они меньше размера бокса и не являются отрицательными.

Если вам интересно, бусинки это:

class particle{
  public:
    vec pos;
    vec oldPos;
    vec vel;
    vec F;
    vec oldF;
    int charge;
    int type;
    double U;
    double nextU;
};

class bead: public particle{
  public: //most of this is redundant...
    int charge;
    int type;
    double rho;
    double nextRho;
    int LID;
    bool keep;
    bool touch;
    double radius;
}

class vec{
  public:
    double x;
    double y;
    double z;
    velarray<double> coor; //on it's way to being canceled
}

Ответы [ 2 ]

4 голосов
/ 15 сентября 2011

При создании shared_ptr<T> вам нужно инициализировать его указателем на тип объекта, который был создан с использованием ключевого слова new, а не с реальным объектом или ссылкой на объект.Например:

shared_ptr<bead> ptr(new bead);

не

bead aBead;
shared_ptr<bead>(aBead);

Кстати, также не делают следующее:

bead* ptr = new bead();
shared_ptr<bead> sptr(ptr);
delete ptr;

shared_ptr<bead>Объект управляет временем жизни указателя.Он будет ссылаться на указатель и вызывать delete для указателя внутри деструктора shared_ptr<T>, когда больше нет ссылок на указатель.Если вы вручную вызовете delete для указателя после инициализации объекта shared_ptr<T>, вы также получите ошибку сегментации, поскольку в основном вы пытались самостоятельно управлять временем жизни памяти, побеждая весь указательуправляемый «умный» указатель типа shared_ptr<T>.

2 голосов
/ 15 сентября 2011

Если у вас есть поддержка C ++ 11, то предпочтительный способ сделать динамический объект плюс общий указатель - make_shared:

boxes[i][j][k].insert(std::make_shared<Bead>());

Если это не удастся, вам придется выполнить динамическое распределение самостоятельно, но с этого момента время жизни объекта будет управляться общим указателем:

boxes[i][j][k].insert(new Bead);

Возможно, вы захотите изменить структуру данных, чтобы избежать чрезмерного использования контейнеров. Каждый контейнер несет выделения, которые могут оказаться дорогими. Если вам нужно плотно заполнить трехмерное пространство, вы можете использовать сглаженный 1-мерный вид, к которому вы получаете доступ по шагам. Если вам нужны только разреженные точки, можно использовать карту на тройках.

...