2013-09-22 6 views
2

В моем классе C++ есть деструктор, который пытается удалить переменные экземпляра std :: vector и std :: array.не может удалить std :: vector & std :: array?

#include <iostream> 
#include <vector> 
#include <array> 

int main() 
{ 
    std::array<int, 3> foo; 
    std::vector< std::array<float, 4> > vertices; 

    foo[0] = 1; 
    foo[1] = 2; 
    foo[2] = 3; 
    std::cout << foo[0] << std::endl; 
    delete foo; 
    delete vertices; 

    return 0; 
} 

Я не уверен, как правильно освободить память - почему я не могу удалить эти переменные?

clang++ -std=c++11 -stdlib=libc++ -Weverything ccc.cpp 
ccc.cpp:14:2: error: cannot delete expression of type 'std::array<int, 3>' 
     delete foo; 
     ^ ~~~ 
ccc.cpp:15:2: error: cannot delete expression of type 'std::vector<std::array<float, 4> 
     >' 
     delete vertices; 
     ^ ~~~~~~~~ 
ccc.cpp:18:2: warning: C++98 requires newline at end of file [-Wc++98-compat-pedantic] 
} 
^ 
+7

Вы ничего не выделяете с помощью 'new', почему вы чувствуете желание освободить что-то с помощью' delete'? Это автоматические переменные - они автоматически уничтожаются, когда они выходят за рамки. –

+0

, даже если они являются переменными-экземплярами-членами в классе? – ejang

+0

Да, у членов класса нет скрытого «нового». – chris

ответ

8

Удалить эти переменные? Единственными «переменными» вы должны delete являются те, которые вы выделили new. Вы выделили что-либо на new в этом коде? Нет. Итак, прекратите пытаться delete что угодно.

Объекты foo и vertices - местные объекты с автоматический срок хранения. Память для этих объектов автоматически распределяется и освобождается автоматически. Вы не можете сделать это сами. Это полностью вне вашего контроля.

Если вы хотите управлять распределением памяти вручную, вам необходимо динамически создавать эти объекты, используя new. Например,

std::array<int, 3> *foo = new std::array<int, 3>(); 
... 
(*foo)[0] = 1; 
(*foo)[1] = 2; 
(*foo)[2] = 3; 
... 
delete foo; 

Вышеуказанное будет работать. Но нет реальной причины привлекать динамическую память в ваш пример. Он работает отлично, как есть, с автоматическими объектами. Просто прекратите пытаться использовать их delete.

delete ожидает указатель как аргумент. Когда вы выделите объекты через new, вы получите доступ к этим объектам с помощью указателей. Эти указатели - это то, что вы позже перейдете к delete, чтобы уничтожить такие объекты. В этом коде ничего из этого не применимо.

+0

Что делать, если содержимое std :: array является указателем на объект. Например, «std :: array myArray1;» .. Если это был «Object * myArray2 [10];», то я мог бы вызвать «delete [] myArray2;», а также вызвать деструктор экземпляров Object , Могу ли я вызвать «delete [] myArray1;» ? – phoad

+0

@phoad: Я не уверен, что понимаю ваш комментарий. Если 'myArray2' был объявлен как' Object * myArray2 [10] ', то вы ** не ** могли бы выполнить' delete [] myArray2'. – AnT

+0

Я помню как «delete [] arr;» вызовет деструктор каждого объекта в «arr» и освободит их. http://www.cplusplus.com/reference/new/operator%20delete[]/ «operator delete [] - это регулярная функция, которая может быть вызвана явно так же, как любая другая функция. Но в C++ delete [] является оператором с очень специфическим поведением: выражение с оператором delete [] сначала вызывает соответствующие деструкторы для каждого элемента в массиве (если они относятся к типу класса), а затем вызывает функцию освобождения массива. ". Должен ли он быть объектом arr [] = new Object [10] вместо Object * arr []? – phoad

Смежные вопросы