Ответ 1
Вы не можете использовать auto_ptr с массивом, потому что он вызывает delete p
, а не delete [] p
.
Вы хотите boost::scoped_array или какой-то другой boost:: smart_array:)
Я использую auto_ptr<>
, который использует массив типа указателя класса, так как я могу присвоить ему значение.
например.
auto_ptr<class*> arr[10];
Как назначить значение массиву arr
?
Вы не можете использовать auto_ptr с массивом, потому что он вызывает delete p
, а не delete [] p
.
Вы хотите boost::scoped_array или какой-то другой boost:: smart_array:)
Если у вас есть С++ 0x (например, MSVC10, GCC >= 4.3), я настоятельно рекомендую использовать либо std::vector<T>
, либо std::array<T, n>
в качестве типа базового объекта (в зависимости от того, установлен ли размер или переменная), и если вы выделите этого парня в кучу и вам нужно передать его, поместите его в std::shared_ptr
:
typedef std::array<T, n> mybox_t;
typedef std::shared_ptr<mybox_t> mybox_p;
mybox_p makeBox() { auto bp = std::make_shared<mybox_t>(...); ...; return bp; }
Массивы и auto_ptr<>
не смешиваются.
Из GotW-сайта:
Каждый
delete
должен соответствовать форме егоnew
. Если вы используете один объект new, вы должны использовать один объект Удалить; если вы используете форму массива new, вы должны использовать форму массива Удалить. В противном случае undefined.
Я не буду копировать сайт GotW дословно; однако я обобщу ваши варианты решения вашей проблемы:
Сбросьте свой собственный автоматический массив
1а. Выведите из auto_ptr. Мало преимуществ, слишком сложно.
1b. Клонировать код auto_ptr. Простота в реализации, отсутствие значительного пространства/накладных расходов. Трудно поддерживать.
Итак, в нижней строке следует использовать vector<>
вместо массивов в стиле C.
Как все говорят здесь, не смешивайте массивы с auto_ptr. Это должно использоваться только тогда, когда у вас есть несколько возвратов, где вам действительно сложно освободить память, или когда вы получаете выделенный указатель из другого места, и вы несете ответственность за его очистку перед существованием функции.
Другое дело, что в деструкторе auto_ptr он вызывает оператор delete с сохраненным указателем. Теперь то, что вы передаете, - это один элемент массива. Менеджер памяти попытается найти и освободить блоки памяти, выделенные от адреса, который вы передаете. Вероятно, это может быть не существующая куча, где сохраняются все распределения. При этой операции вы можете испытать поведение undefined, такое как сбой, повреждение памяти и т.д.