how to create a contiguous 2d array in c++?

后端 未结 7 1607
走了就别回头了
走了就别回头了 2020-11-21 23:52

I want to create a function that returns a contiguous 2D array in C++.

It is not a problem to create the array using the command:

 int (*v)[cols] = n         


        
7条回答
  •  萌比男神i
    2020-11-22 00:25

    The "Rudimentary RAll" class provided by PaulMcKenzie is an excellent solution. In my use of it I did find a memory leak which is fixed in the version shown below.

    The memory leak was due to an issue with Array2D& operator=(Array2D&& rhs) noexcept.

    The statement rhs.m_dataPtr = nullPtr needed to be removed in order to allow the rhs destructor to delete the original data (pool and pointers) swapped from lhs.

    Here is the corrected code for the "Rudimentary RAll" class provided by PaulMcKenzie

    template 
    class Array2D
    {
        T** data_ptr;
        unsigned m_rows;
        unsigned m_cols;
    
        T** create2DArray(unsigned nrows, unsigned ncols, const T& val = T())
        {
            T** ptr = nullptr;
            T* pool = nullptr;
            try
            {
                ptr = new T*[nrows];  // allocate pointers (can throw here)
                pool = new T[nrows*ncols]{ val };  // allocate pool (can throw here)
    
                // now point the row pointers to the appropriate positions in
                // the memory pool
                for (unsigned i = 0; i < nrows; ++i, pool += ncols)
                    ptr[i] = pool;
    
                // Done.
                return ptr;
            }
            catch (std::bad_alloc& ex)
            {
                delete[] ptr; // either this is nullptr or it was allocated
                throw ex;  // memory allocation error
            }
        }
    
    public:
        typedef T value_type;
        T** data() {
            return data_ptr;
        }
    
        unsigned get_rows() const {
            return m_rows;
        }
    
        unsigned get_cols() const {
            return m_cols;
        }
    
        Array2D() : data_ptr(nullptr), m_rows(0), m_cols(0) {}
        Array2D(unsigned rows, unsigned cols, const T& val = T())
        {
            if (rows == 0)
                throw std::invalid_argument("number of rows is 0");
            if (cols == 0)
                throw std::invalid_argument("number of columns is 0");
            data_ptr = create2DArray(rows, cols, val);
            m_rows = rows;
            m_cols = cols;
        }
    
        ~Array2D()
        {
            if (data_ptr)
            {
                delete[] data_ptr[0];  // remove the pool
                delete[] data_ptr;     // remove the pointers
            }
        }
    
        Array2D(const Array2D& rhs) : m_rows(rhs.m_rows), m_cols(rhs.m_cols)
        {
            data_ptr = create2DArray(m_rows, m_cols);
            std::copy(&rhs.data_ptr[0][0], &rhs.data_ptr[m_rows-1][m_cols], &data_ptr[0][0]);
        }
    
        Array2D(Array2D&& rhs) noexcept
        {
            data_ptr = rhs.data_ptr;
            m_rows = rhs.m_rows;
            m_cols = rhs.m_cols;
            rhs.data_ptr = nullptr;
        }
    
        Array2D& operator=(Array2D&& rhs) noexcept
        {
            if (&rhs != this)
            {
                swap(rhs, *this);
            }
            return *this;
        }
    
        void swap(Array2D& left, Array2D& right)
        {
            std::swap(left.data_ptr, right.data_ptr);
            std::swap(left.m_cols, right.m_cols);
            std::swap(left.m_rows, right.m_rows);
        }
    
        Array2D& operator = (const Array2D& rhs)
        {
            if (&rhs != this)
            {
                Array2D temp(rhs);
                swap(*this, temp);
            }
            return *this;
        }
    
        T* operator[](unsigned row)
        {
            return data_ptr[row];
        }
    
        const T* operator[](unsigned row) const
        {
            return data_ptr[row];
        }
    
        void create(unsigned rows, unsigned cols, const T& val = T())
        {
            *this = Array2D(rows, cols, val);
        }
    };
    
    int main()
    {
        try
        {
            Array2D dPtr(10, 10);
            std::cout << dPtr[0][0] << " " << a2[0][0] << "\n";
        }
        catch (std::exception& ex)
        {
            std::cout << ex.what();
        }
    }
    

提交回复
热议问题