14

如果我使用声明一个临时自动删除的字符缓冲区

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

然后缓冲区超出范围时会自动删除。我会假设缓冲区是使用 delete 删除的。

但是缓冲区是使用 new[] 创建的,因此严格来说应该使用 delete[] 删除缓冲区。

这种不匹配可能导致内存泄漏的可能性有多大?

4

8 回答 8

19

在使用 new[] 分配的指针上调用 delete 的行为是undefined。正如您所假设的,当智能指针超出范围时, auto_ptr确实会调用 delete 。您需要担心的不仅仅是内存泄漏——崩溃和其他奇怪的行为也是可能的。

如果你不需要转移指针的所有权,Boost 的scoped_array类可能就是你要找的。

于 2008-11-04T09:40:45.683 回答
10

我会使用 char 的向量作为缓冲区。

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

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

基本上,如果不需要,您甚至都不想调用 new 。
向量提供了一个运行时大小的缓冲区,您可以像使用数组(缓冲区)一样使用它。

最好的部分是向量会自行清理,并且标准保证向量中的所有元素都将在连续存储中。完美的缓冲。

或更正式的保证是:

(&buffer[0]) + size == (&buffer[size])
于 2008-11-04T18:12:11.190 回答
7

这会产生未定义的行为(可能比内存泄漏更糟糕,例如堆损坏)尝试使用boost 的 scoped_array 或 shared_array代替。

于 2008-11-04T09:41:09.193 回答
6

对使用 new[] 分配的数据调用 delete 是未定义的。这意味着编译器可以生成可以做任何事情的代码。但是在这种情况下,它可能会起作用,因为不需要破坏数组中的单个字符,只需破坏数组本身。

由于这种行为是未定义的,我强烈建议使用std::vector<char>orboost::scoped_array<char> / boost::shared_array<char>代替。std::auto_ptr<>在这种情况下,所有这些都是完全可行和优越的选择。如果您使用std::vector,您还可以根据需要动态增加缓冲区。

于 2008-11-04T09:42:30.033 回答
5

有充分的理由不使用 std::string 吗?std::vector,正如其他人所建议的那样?你做的是错的,但是不知道你在做什么,推荐别的东西是很困难的。

于 2008-11-04T18:20:17.477 回答
4

是的,这是错误的。用一个简单的包装器包装。

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] );
于 2008-11-10T20:20:09.603 回答
2

自从提出这个问题以来已经过去了几年。

但是我通过搜索点击了这个页面,所以我想我不妨注意一下: std::unique_ptr是 auto_ptr 的 C++11 替代品,可以处理使用 new[] 创建的对象的删除。

std::unique_ptr 有两个版本: 1) 管理单个对象的生命周期(例如用 new 分配)2) 管理动态分配的对象数组的生命周期(例如用 new[] 分配)

cppreference unique_ptr

于 2012-07-17T00:33:39.107 回答
0

对于一个非常简单的解决方案来说,这似乎非常复杂。你使用有什么问题

 char *c=new char[n] 

在这里,然后删除它?或者,如果您需要更动态的解决方案,

vector<char> c

奥卡姆剃刀,伙计。:-)

于 2008-11-04T18:52:46.600 回答