【问题标题】:How can I create a destructor to check if the pointer is NULL? If not, delete the memory that has been allocated for the pointer如何创建一个析构函数来检查指针是否为 NULL?如果不是,删除已经为指针分配的内存
【发布时间】:2023-02-02 15:06:16
【问题描述】:
CheckedArray::CheckedArray(int size) :mSize(size){
    int *mArray = new int[size];
    for(int i = 0; i < size; i++)
          mArray[i] = 0;
}

CheckedArray::~CheckedArray() {
    if (mArray == NULL){
        return;
    }
    else {
        delete[] mArray;
    }
}

我正在使用动态内存分配来创建一个新数组。我想检查指针是否为空,然后返回。如果没有,则删除。我收到这些错误消息,但我不知道出了什么问题。

(9094,0x100094600) malloc: *** 对象 0x10001e7b3 错误:未分配正在释放的指针

(9094,0x100094600) malloc: *** 在 malloc_error_break 中设置断点进行调试

【问题讨论】:

  • 为什么不使用 std::unique_ptr<int[]>? avoid calling new/delete explicitly 并使其成为成员变量
  • int *mArray = new int[size]; 创建一个局部变量和内存泄漏,因为一旦函数结束,指针就会丢失。如果您有一个名为mArray 的成员变量,那么您将改用mArray = new int[size];。在删除指针之前无需检查指针是否为NULL。删除 NULL 指针很好,只是一个 nop。
  • 其他注意事项,不要使用NULL,而是在C++中使用nullptr。并且在你所有的构造函数中初始化一个指向 nullptr 的成员变量指针,除非你真的分配内存。
  • 您使用成员初始值设定项列表来初始化大小,为什么不对数组也这样做呢?

标签: c++ pointers constructor dynamic-memory-allocation destructor


【解决方案1】:

这是 std::unique_ptr 可以为您做什么的示例:

#include <iostream>
#include <algorithm>
#include <memory>

// https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r11-avoid-calling-new-and-delete-explicitly
// so use https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique
// prefer range based for loops, they can't go out of bounds : https://en.cppreference.com/w/cpp/language/range-for

class dynamic_int_array_t final
{
public:
    // creates an "empty array" with enough memory for 4 ints.
    dynamic_int_array_t() :
        m_capacity{ 4ul },  // start with a capacity for 4 ints.
        m_size{ 0ul },      // but actually none are stored yet
        m_values{ std::make_unique<int[]>(m_capacity) }
    {
    }

    // allows you to construct an array from a list of integers
    dynamic_int_array_t(std::initializer_list<int>&& values) :
        m_capacity{ values.size() },
        m_size{ values.size() },
        m_values{ std::make_unique<int[]>(m_capacity) }
    {
        std::copy(values.begin(), values.end(), m_values.get());
    }

    ~dynamic_int_array_t() = default; // destructor will destruct unique_ptr and free memory

    // non-copyable non-movable (simplifies things for now)
    dynamic_int_array_t(const dynamic_int_array_t&) = delete;
    dynamic_int_array_t& operator=(const dynamic_int_array_t&) = delete;
    dynamic_int_array_t(dynamic_int_array_t&&) = delete;
    dynamic_int_array_t& operator=(dynamic_int_array_t&&) = delete;

    // begin and end allow range based for loops to work
    // range based for loops don't allow you to go out of bounds.
    auto begin() const
    {
        return m_values.get();
    }

    // end should point "one past" the array (that's how end works)
    auto end() const
    {
        int* ptr = begin();
        ptr += m_size;
        return ptr;
    }

    std::size_t size() const
    {
        return m_size;
    }

    void add(const int value)
    {
        // if not enough memory then allocate more
        if (m_size == m_capacity) grow_capacity();

        // add new value at the end
        m_values[m_size] = value;
        m_size++;
    }

    // add another array to this one
    void append(const dynamic_int_array_t& rhs)
    {
        for (int value : rhs)
        {
            add(value);
        }
    }

private:

    void grow_capacity()
    {
        m_capacity *= 2;

        // allocate new memory
        auto tmp = std::make_unique<int[]>(m_capacity);

        // copy content to new memory
        std::copy(begin(), end(), tmp.get());

        // swap new memory with tmp so m_values will now be the newly allocated memory and tmp will hold the previously allocated memory
        std::swap(tmp, m_values);

        // tmp will go out of scope and delete old buffer
    }

    std::size_t m_capacity;
    std::size_t m_size;
    std::unique_ptr<int[]> m_values;
};

int main()
{
    dynamic_int_array_t array{ 4,5 };

    for (int n = 10; n < 20; ++n)
    {
        array.add(n);
    }

    for (const int value : array)
    {
        std::cout << value << " ";
    }
    

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-07
    • 2011-09-05
    • 2019-12-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2016-05-06
    相关资源
    最近更新 更多