Via stackoverflow threads like this one, I discovered that you could use an array of pointers to manage a 2D array. In the past I used to use pointer to pointer to store 2D arrays, but now I have a requirement to store my data in contiguous memory, so pointer to pointer format doesn't work anymore.
A raw 2D array is an alternative to array of pointers, but raw 2D array doesn't work for me because I want to be able to allocate storage in the heap and not on the stack because my container can be very large and I might encounter stack overflow if I use vanilla 2D array.
My question is about how memory is allocated for array of pointers. I use new operator like below (see my constructor) to allocate my array of pointers
#include <iostream>
using namespace std;
template<typename DataType, unsigned numRows, unsigned numCols>
class Container2D {
public:
Container2D() {
m_data = new DataType[numRows][numCols];
}
~Container2D() {
delete [] m_data;
}
DataType* getData() { return &m_data[0][0]; }
private:
DataType (*m_data)[numCols];
};
int main() {
Container2D<int, 3, 3> container;
return 0;
}
Does new DataType[numRows][numCols] allocate the entire 2D array on the heap or does it allocate numRows pointers on the heap while allocating numCols objects of type DataType on the stack?
In a pointer to pointer scenario (where I'd define my storage as DataType** m_data), I know for a fact that both dimensions of my array are allocated on the heap and I would call delete m_data[i] for each column and then call delete[] m_data to free my row data. In the array of pointers scenario, I'm not sure if my destructor above is freeing up data correctly.
new/deletedo use heap on systems that have a heap. Instead of using a pointer andnew/delete, try using a suitable standard container.std::vector<std::vector<DataType> >can be used to represent a 2D array if contiguity of rows/columns doesn't matter, andstd::vector<DataType>(with suitable mapping of indices) can be used if contiguity matters. The default allocator forstd::vectorusesnew/delete(so, if you follow basic guidelines to usestd::vectorcorrectly) will correctly manage/release memory (e.g. avoid leaks)std::unique_ptr<std::array<std::array<T, numCols>, numRows>>- examplestd::vectorto manage your memory?