【问题标题】:Is it wrong to use auto_ptr with new char[n]将 auto_ptr 与 new char[n] 一起使用是否错误
【发布时间】:2010-09-20 15:40:21
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: c++ stl memory-leaks auto-ptr


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      这会产生未定义的行为(可能比内存泄漏更严重,例如堆损坏)尝试使用boost's scoped_array or shared_array

      【讨论】:

        【解决方案3】:

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

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

        【讨论】:

          【解决方案4】:

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

          std::vector<char>    buffer(size);
          
          read(input,&buffer[0],size);
          

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

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

          或更正式的保证是:

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

          【讨论】:

            【解决方案5】:

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

            【讨论】:

              【解决方案6】:

              对于一个非常简单的解决方案来说,这似乎非常复杂。你怎么了

               char *c=new char[n] 
              

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

              vector<char> c
              

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

              【讨论】:

              • 重点是保证删除。使用智能指针/数组对正常的编程错误是安全的,并且足够智能以在发生异常时释放内存。直接使用 C 数组是要求内存泄漏。
              • 重点是我们要保证删除。因此,未包装的 RAW new 不是一个好的答案。另一方面,std::vector 是一个很好的答案
              【解决方案7】:

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

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

              【讨论】:

                【解决方案8】:

                问这个问题已经过去几年了。

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

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

                cppreference unique_ptr

                【讨论】:

                • 这不是特定于“MSDN”的吗(不过,cl 是那个编译器的名称。)
                • 很公平。将参考更新为通用 C++ 而不是特定于 Microsoft-STL。其他答案在 2008 年第一次被问到时很好,但现在 auto_ptr 早已被弃用,我只希望没有新手网络冲浪者点击这个页面并认为他们需要提升或他们自己的包装器或其他任何东西,当好的解决方案是免费的 STL现在。
                猜你喜欢
                • 2023-04-06
                • 2012-07-26
                • 2010-09-11
                • 1970-01-01
                • 2013-05-14
                相关资源
                最近更新 更多