Home > Enterprise >  How can I create a destructor to check if the pointer is NULL? If not, delete the memory that has be
How can I create a destructor to check if the pointer is NULL? If not, delete the memory that has be

Time:02-02

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;
    }
}

I'm using dynamic memory allocation to create a new array. I want to check if the pointer is null, then return. If not, then delete. I'm getting these error messages, but I have no idea what's wrong.

(9094,0x100094600) malloc: *** error for object 0x10001e7b3: pointer being freed was not allocated

(9094,0x100094600) malloc: *** set a breakpoint in malloc_error_break to debug

CodePudding user response:

To be completely clear

CheckedArray::CheckedArray(int size) :mSize(size){
    int *mArray = new int[size];
    for(int i = 0; i < size; i  )
          mArray[i] = 0;
}

should be

CheckedArray::CheckedArray(int size) :mSize(size), mArray(new int[size]){
    for(int i = 0; i < size; i  )
          mArray[i] = 0;
}

Your version creates a local variable mArray which shadows the class variable of the same name.

CodePudding user response:

Here is an example of what std::unique_ptr can do for you :

#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;
}
  • Related