Резервирование и удаление векторов? - PullRequest
2 голосов
/ 16 мая 2011

У меня проблема с удалением данных вектора.

Когда я создаю данные, я сначала резервирую пространство в массиве, затем изменяю размер вектора и копирую адреса массива:

//Create the vertices
verts.reserve(vn); verts.resize(vn);
TriVertex *vertsaux = new TriVertex[vn];

for(int i=0, c=0; i<vn; i++, c+=3)
{
     vertsaux[i].SetId(i);
     vertsaux[i].SetCoords0(Vector3(vs[c], vs[c+1], vs[c+2]));

     //Inicializate texture vertices
     vertsaux[i].SetTextureCoords(Vector2(0.0f, 0.0f));
}

for(int i=0; i<vn; i++)
{
     verts[i] = &vertsaux[i];
}

Но в деструкторе моего класса это выдает ошибку времени выполнения, когда я делаю это:

for (i=0; i < this->verts.size(); i++) {
     delete this->verts[i];
}

Кто-нибудь знает, почему это происходит?

Кстати, я не могу просто создать new TriVertex внутри for из-за некоторых деталей реализации ...

Ответы [ 6 ]

3 голосов
/ 16 мая 2011

Вы выделяете массив объектов с помощью

TriVertex *vertsaux = new TriVertex[vn];

Чтобы удалить это снова, вам нужно сделать

delete[] vertsaux;

Вы не можете удалять элементы по отдельности.

1 голос
/ 16 мая 2011

Вы не даете нам достаточно информации.Какой это тип verts?И почему вы используете versaux?Из того, что я вижу, наиболее логичным решением было бы иметь std::vector <TriVertex> verts; в качестве члена класса и инициализировать его напрямую, без промежуточных динамических распределений.Возможно:

verts.reserve(vn);

for ( int i = 0; i < vn; ++ i ) {
    verts.push_back( TriVertex() );
    TriVertex& current = verts.back();
    current.SetId( i );
    current.SetCoords( Vector3( *vs, *(vs+1), *(vs+ 2) ) );

    current.SetTextureCoords( Vector2( 0.0, 0.0 ) );
    vs += 3;
}

Я не вижу причин для промежуточного, динамически размещаемого массива.(Если есть, ответ Джо является правильным.)

0 голосов
/ 16 мая 2011

Здесь есть две вещи:

  1. Как указали многие люди, выделение массива требует удаления как массива.Тем не менее, я думаю, что это маскирует то, что вы действительно пытаетесь сделать здесь.Измените свое распределение, чтобы сделать «new TriVertex» для каждого элемента.

  2. Если ваш вектор хранит TriVertex* указателей, вы действительно должны удалить каждый элемент в своем деструкторенаписал.)

Таким образом, исправление вашей первоначальной стратегии распределения для TriVertex объектов должно решить проблему.

for(int i=0, c=0; i<vn; i++, c+=3)
{
    TriVertex *vertsaux = new TriVertex;

    vertsaux->SetId(i);
    vertsaux->SetCoords0(Vector3(vs[c], vs[c+1], vs[c+2]));

    //Initializing texture vertices
    vertsaux->SetTextureCoords(Vector2(0.0f, 0.0f));
    verts[i] = vertsaux;
}
0 голосов
/ 16 мая 2011

Когда вы выделяете массив с помощью

TriVertex *vertsaux = new TriVertex[vn];

Вы должны освободить, используя delete[], позвонив

delete[] vertsaux;
0 голосов
/ 16 мая 2011

Так как вы создаете массив TriVertex, на который указывает vertsaux, вы должны удалить массив, используя:

delete[] vertsaux;

Вы не можете удалить отдельные элементы массива.

Сделав выше delete[], вы должны удалить все элементы verts следующим образом:

verts.clear();

Это потому что вы удалили vertsaux, указатели внутри verts неверны.

Я предполагаю, что verts - это что-то вроде: std::vector<TriVertex*>

0 голосов
/ 16 мая 2011
delete this->verts[i];

Это удаляет один элемент в динамически распределенном массиве, который вы создали, и фактически является UB, чтобы удалить его таким образом.

Подобный массив должен быть удален с помощью оператора delete[], который удаляет весь массив .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...