Как правильно использовать auto_ptr для динамически размещаемых массивов? - PullRequest
3 голосов
/ 01 июня 2010

Если я использую auto_ptr для хранения указателя на динамически распределенный массив, когда auto_ptr будет убит, он будет использовать простую операцию delete , а не delete [] , таким образом, не удаляя мой выделенный массив.

Как я могу (правильно) использовать auto_ptr для динамически размещаемых массивов?

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

Заранее спасибо.

Ответы [ 5 ]

10 голосов
/ 01 июня 2010

Ты не. std::auto_ptr не предназначен для использования с массивами.

Избегайте использования new[] и delete[]. Используйте std::vector вместо этого. Это тоже рекомендация Страуструпа.

Если вы используете массив, потому что вам нужно передать его в код, который ожидает указатель, вы можете просто передать адрес первого элемента (непустого) вектора. Например:

std::vector<char> buf(size);
fgets(&buf[0], buf.size(), stdin);

Обратите внимание, что в C ++ 11 вы можете (и должны) использовать buf.data() вместо &buf[0]; buf.data() работает и с пустым вектором.

5 голосов
/ 01 июня 2010

boost :: shared_array - это то, что вы ищете.

EDIT:

Если вы хотите избежать использования boost, я бы порекомендовал просто использовать std::vector, они находятся под массивом, и вам не нужно беспокоиться о распределении памяти. На самом деле это лучшее решение, чем shared_array в любом случае.

Поскольку вы указываете, что хотите использовать auto_ptr, вам не нужна модель подсчета ссылок и владения shared_array. Так что просто используйте std :: vector , так как они предназначены для замены динамически размещаемых массивов, и это действительно то, чем вы пытаетесь управлять с помощью auto_ptr.

1 голос
/ 01 июня 2010

Правильный интеллектуальный указатель наддува в этом случае - boost :: scoped_array , а не более известный boost :: shared_array, поскольку std::auto_ptr является указателем единоличного владения. напротив указателя общего владения. В C ++ 0x правильный указатель - std::unique_ptr, который вызовет delete [], если он указывает на массив, или delete, если он указывает на один объект.

1 голос
/ 01 июня 2010

Если вы хотите сделать это самостоятельно (т.е. не использовать boost), то сначала оберните динамический массив в класс. Пусть деструктор класса вызовет delete[]. Тогда auto_ptr<Wrapper> может вызвать delete для класса, и память будет правильно освобождена.

0 голосов
/ 01 июня 2010

Правильный способ использования auto_ptr (с динамически размещаемым массивом или чем-то еще) - использовать вместо этого что-то еще. Либо boost :: shared_array или shared_ptr> или shared_ptr> из TR1 в вашем случае. В общем случае shared_ptr или unique_ptr - это умные указатели, которые на самом деле умные. Прекратить использование auto_ptr.

...