将 auto_ptr 与 new char[n] 一起使用是否错误

发布于 2024-07-07 15:09:08 字数 237 浏览 8 评论 0原文

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

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

那么当缓冲区超出范围时,该缓冲区将自动删除。 我假设使用delete删除了缓冲区。

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

这种不匹配有什么可能导致内存泄漏?

If I declare a temporary auto deleted character buffer using

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

then the buffer is automatically deleted when the buffer goes out of scope. I would assume that the buffer is deleted using delete.

However the buffer was created using new[], and so strictly speaking the buffer should be deleted using delete[].

What possibility is there that this mismatch might cause a memory leak?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

撩人痒 2024-07-14 15:09:09

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

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

The behaviour of calling delete on a pointer allocated with new[] is undefined. As you assumed, auto_ptr does call delete when the smart pointer goes out of scope. It's not just memory leaks you have to worry about -- crashes and other odd behaviours are possible.

If you don't need to transfer the ownership of the pointer, Boost's scoped_array class might be what you're looking for.

忆悲凉 2024-07-14 15:09:09

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

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

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

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

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

或者更正式地说,保证是:

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

I would use a vector of char as the buffer.

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

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

Basically you don't even want to call new if you don't need to.
A vector provides a run-time sized buffer that you can use just like an array (buffer).

The best part is that the vector cleans up after itself and the standard guarantees that all element in the vector will be in contigious storage. Perfect for a buffer.

Or more formaly the guarantee is:

(&buffer[0]) + size == (&buffer[size])
反差帅 2024-07-14 15:09:09

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

That yields undefined behaviour (could be worse than memory leak, for instance heap corruption) try boost's scoped_array or shared_array instead.

苯莒 2024-07-14 15:09:09

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

尽管如此,由于此行为未定义,我强烈建议使用 std::vectorboost::scoped_array; / boost::shared_array 代替。 在这种情况下,所有这些都是完全可行且优于使用 std::auto_ptr 的选项。 如果您使用 std::vector ,您还可以根据需要动态增长缓冲区。

Calling delete on data allocated with new[] is undefined. This means that the compiler may generate code that may do anything. However in this case it probably works since there's no need to destruct the individual chars in the array, just the array itself.

Still since this behavior is undefined, I would strongly recommend using std::vector<char> or boost::scoped_array<char> / boost::shared_array<char> instead. All are perfectly viable and superior options to using std::auto_ptr<> in this case. If you use std::vector you also have the possibility of dynamically grow the buffer if required.

一身骄傲 2024-07-14 15:09:09

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

Is there a good reason not to use std::string? std::vector, as other have suggested? What you're doing is wrong, but without knowing what you're trying to do recommending something else is difficult.

倚栏听风 2024-07-14 15:09:09

是的,这是错误的。 用一个简单的包装纸包裹起来。

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] );

Yes, it is wrong. Wrap with a trivial wrapper.

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] );
埋葬我深情 2024-07-14 15:09:09

距离提出这个问题已经过去了几年。

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

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

cppreference unique_ptr< /a>

A few years have passed since the question was asked.

But I hit this page from a search, so I figured I might as well note:
std::unique_ptr, the C++11 replacement for auto_ptr, can handle deletion of objects created with new[].

There are two versions of std::unique_ptr: 1) Manages the lifetime of
a single object (e.g. allocated with new) 2) Manages the lifetime of a
dynamically-allocated array of objects (e.g. allocated with new[])

cppreference unique_ptr

花期渐远 2024-07-14 15:09:09

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

 char *c=new char[n] 

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

vector<char> c

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

This seems awful complex for a very simple solution. What's wrong with you using

 char *c=new char[n] 

here, and then deleting it?
Or, if you need a bit more dynamic solution,

vector<char> c

Occam's Razor, man. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文