Подтвердить что ты не робот

Неправильно ли использовать auto_ptr с новым char [n]

Если я объявляю временный автоматически удаленный буфер символов, используя

std::auto_ptr<char> buffer(new char[n]);

тогда буфер автоматически удаляется, когда буфер выходит из области видимости. Я бы предположил, что буфер удаляется с помощью delete.

Однако буфер был создан с использованием new [], и, строго говоря, буфер нужно удалить с помощью delete [].

Какая вероятность того, что это несоответствие может вызвать утечку памяти?

4b9b3361

Ответ 1

Поведение вызова delete по указателю, выделенному новым [], undefined. Как вы предполагали, auto_ptr выполняет удаление, когда интеллектуальный указатель выходит из области видимости. Это не просто утечка памяти, о которой вы должны беспокоиться - возможны сбои и другие странные поведения.

Если вам не нужно передавать права собственности на указатель, Boost scoped_array класс может быть тем, что вы ищете.

Ответ 2

Я бы использовал в качестве буфера вектор char.

std::vector<char>    buffer(size);

read(input,&buffer[0],size);

В принципе, вы даже не хотите называть новое, если вам не нужно.
Вектор предоставляет буфер времени выполнения, который можно использовать точно так же, как массив (буфер).

Лучшая часть состоит в том, что вектор очищается после себя, а стандарт гарантирует, что весь элемент в векторе будет находиться в свободном хранилище. Идеально подходит для буфера.

Или более формально гарантия:

(&buffer[0]) + size == (&buffer[size])

Ответ 3

Это дает поведение undefined (может быть хуже утечки памяти, например, кучное повреждение) вместо boost scoped_array или shared_array.

Ответ 4

Вызов удаления по данным, выделенным новым [], составляет undefined. Это означает, что компилятор может генерировать код, который может что-то сделать. Однако в этом случае он, вероятно, работает, поскольку нет необходимости уничтожать отдельные символы в массиве, только сам массив.

Тем не менее, поскольку это поведение undefined, я бы настоятельно рекомендовал вместо этого использовать std::vector<char> или boost::scoped_array<char> / boost::shared_array<char>. В этом случае все они являются вполне жизнеспособными и превосходят возможности использования std::auto_ptr<>. Если вы используете std::vector, вы также можете динамически увеличивать буфер, если это необходимо.

Ответ 5

Есть ли веская причина не использовать std::string? std::vector, как предложили другие? То, что вы делаете, неверно, но не зная, что вы пытаетесь сделать, чтобы рекомендовать что-то другое, сложно.

Ответ 6

Да, это неправильно. Оберните тривиальной оберткой.

typedef< typename T_ >
struct auto_vec{
  T_* t_;
  auto_vec( T_* t ): t_( t ) {}
  ~auto_vec() { delete[] t_; }
  T_* get() const { return t_; }
  T_* operator->() const { return get(); }
  T_& operator*() const { return *get(); }
  /* you should also define operator=, reset and release, if you plan to use them */
}

auto_vec<char> buffer( new char[n] );

Ответ 7

Несколько лет прошло с тех пор, как был задан вопрос.

Но я ударил эту страницу из поиска, поэтому я подумал, что могу также отметить: std:: unique_ptr, замена С++ 11 для auto_ptr, может обрабатывать удаление объектов, созданных с помощью нового [].

Существуют две версии std:: unique_ptr: 1) Управляет временем жизни один объект (например, назначенный новым) 2) Управляет временем жизни динамически распределенный массив объектов (например, назначенный новым [])

cppreference unique_ptr

Ответ 8

Это кажется очень сложным для очень простого решения. Что не так с вами, используя

 char *c=new char[n] 

здесь, а затем удалив его? Или, если вам нужно немного более динамичное решение,

vector<char> c

Оккам Бритва, мужик.: -)