【问题标题】:auto_ptr with an array of POD and uninitialized values带有 POD 数组和未初始化值的 auto_ptr
【发布时间】:2015-09-30 14:20:05
【问题描述】:

这与auto_ptr for arrays 非常相似。但是,我的问题是我不想要一个初始化数组,这是 vector 将提供的(const T& value = T()):

explicit vector(size_type count,
    const T& value = T(),
    const Allocator& alloc = Allocator());

我不希望数组初始化,因为它是一个大数组,并且值将被立即丢弃。

我目前正在使用以下内容对其进行破解,但感觉好像有问题:

//! deletes an array on the heap.
template <class T>
class AutoCleanup
{
public:
    AutoCleanup(T*& ptr) : m_ptr(ptr) { }
    ~AutoCleanup() { if (m_ptr) { delete[] m_ptr; m_ptr = NULL; }}

private:
    T*& m_ptr;
};

还有:

// AutoCleanup due to Enterprise Analysis finding on the stack based array.
byte* plaintext = new byte[20480];
AutoCleanup<byte> cleanup(plaintext);

// Do something that could throw...

C++ 为未初始化并正确删除的 POD 类型数组提供什么?


项目是C++03,没有像Boost这样的外部依赖。

【问题讨论】:

  • 你的意思是非 Boost boost::ptr_vector?
  • 为什么会被立即丢弃?您要解决的实际问题是什么?
  • 我不认为 new[] 和 delete[] 初始化 POD 元素..
  • 请注意,auto_ptr 自 C++11 以来已被弃用,并将随 C++17 消失。
  • @ʎǝɹɟɟɟǝſ - “为什么会立即丢弃它们?” - 数组中的值会立即被覆盖。 “您要解决的实际问题是什么?” - 企业分析在放置在堆栈上的大型阵列上发现。我对此有些无所谓,但我想确保那些使用分析工具的人不会遇到任何发现。

标签: c++ arrays memory-management c++03


【解决方案1】:

根据您的问题,要解释您实际需要什么并不容易。但我猜你想要一个受堆栈保护(即绑定到堆栈的生存期)、堆分配、未初始化、动态或静态大小并与 C++11 之前的编译器兼容的数组。

auto_ptr 无法处理数组(因为它在其析构函数中不调用delete[],而是调用delete)。

相反,我会使用 boost::scoped_arraynew[](它不会初始化 POD 类型 afaik)。

boost::scoped_array<MyPodType> a(new MyPodType[20480]);

如果你不想使用 boost,你可以很容易地重新实现 scoped_array,方法是将这个类包含的来自 boost 库的代码粘贴在一起:

#include <cassert>
#include <cstddef>

// From <boost/checked_delete.hpp>:
template<class T>
inline void checked_array_delete(T * x)                                                                          
{
    typedef char type_must_be_complete[sizeof(T) ? 1 : -1];
    (void) sizeof(type_must_be_complete);
    delete [] x;
}

// From <boost/smartptr/scoped_array.hpp>:
template<class T>
class scoped_array
{
private:
    T * px;

    // Make this smart pointer non-copyable
    scoped_array(scoped_array const &);
    scoped_array & operator=(scoped_array const &);

    typedef scoped_array<T> this_type;

public:
    typedef T element_type;

    explicit scoped_array(T * p = 0) : px(p)  { }

    ~scoped_array() {
        checked_array_delete(px);
    }

    void reset(T * p = 0) {
        assert(p == 0 || p != px); // catch self-reset errors
        this_type(p).swap(*this);
    }

    T & operator[](std::ptrdiff_t i) const {
        assert(px != 0);
        assert(i >= 0);
        return px[i];
    }

    T * get() const {
        return px;
    }

    operator bool () const {
        return px != 0;
    }

    bool operator ! () const {
        return px == 0;
    }

    void swap(scoped_array & b) {
        T * tmp = b.px;
        b.px = px;
        px = tmp;
    }
};

【讨论】:

  • 谢谢利姆斯。我真的不知道这是否是我需要的。是否会确保 (1) 使用 new [] 创建的值未初始化; (2) 数组在销毁时用delete [] 删除?如果它满足这两个标准,那么我很乐意接受。
  • @Jarod42 哦,你说得对……那我就删掉explicit
  • @jww AFAIK,两者都是真的。这个类只是简单地包裹delete[] 并且不做任何分配或初始化。这是在您创建包装类的实例时完成的,因为您只给它一个指向要删除的数组的指针。在那里你使用new[],它不会初始化 POD 类型。
  • 完美,谢谢。一直以来,我都认为我做错了什么(而且太不了解 C++ 的方式)。看起来 Boost 和我以同样的方式解决了这个问题。
  • 是的...您在问题中添加的内容几乎就是解决方案。我的其余答案/ boost 实现只是简单符号的便利成员,例如operator[]
猜你喜欢
  • 1970-01-01
  • 2011-04-25
  • 2017-06-19
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多