Jump to content
  • Advertisement
Sign in to follow this  
CrimsonMemory

Question regarding deleting pointers to matrices

This topic is 4066 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's say I create a pointer to a matrix of doubles, as such:
double** matrix = new double*[10];
for (int i=0; i<10; i++)
    matrix = new double[10];

Now, if I were planning to delete said pointer, would I just invoke the delete[] operator, like this?
delete [] matrix;

Or does delete[] not act recursively, causing me to do it this way:
for (int i = 0; i<10; ++i)
    delete [] matrix;

This is basically a question about how exactly delete[] operates. Thanks in advance!

Share this post


Link to post
Share on other sites
Advertisement
It's hacky, but there's a method that simplifies both the memory layout (potentially helping the cache) as well as the cleanup, at the cost of a messy looking initialization. The idea is to allocate all the memory in one single chunk, set up pointers of the first array to point into the rest of the buffer as if it were a series of independent arrays. Here's the basic idea, minus fancies (such as templatizing the function):
double** Allocate2DArray(unsigned int width, unsigned int height)
{
char* buffer = new char[sizeof(double*) * width + sizeof(double) * width * height];
double** firstDimension = reinterpret_cast<double**>(buffer);
double* secondDimension = reinterpret_cast<double*>(buffer + sizeof(double*) * width);
double** firstDimensionEnd = firstDimension + width;
while (firstDimension < firstDimensionEnd)
{
*firstDimension = secondDimension;
firstDimension += 1;
secondDimension += height;
}

return reinterpret_cast<double**>(buffer);
}

void Deallocate2DArray(double** array)
{
//Note: I'm not sure the reinterpret_cast back into what the
//array was allocated as is necessary, but I'm doing it just to
//be safe.
delete [] reinterpret_cast<char*>(array);
}

int main()
{
double** array= Allocate2DArray(4, 3);

array[0][0] = 5.0;
array[3][2] = 7.0;
//etc.

Deallocate2DArray(array);
}


Now I'm more inclined to encourage the method that I'm pretty confident is used by Boost::MultiArray, which is to just allocate an ordinary single-dimension array, wrap it up in a class, and then do the appropriate multiplications and additions within the subscript operator's ([]) body. (Or even better, just use Boost::MultiArray itself!) However, the method above does have the benefit of requiring no multiplications, at the cost of a little bit extra memory for the first dimension array of pointers. In some cases this might be better, but I wouldn't be surprised if it wasn't. Wrapping all this up in a class also has plenty of other benefits, such as being able to store the size/shape of the multi-dimensioned array.

Share this post


Link to post
Share on other sites
I had considered both of your alternatives, and, as logical and good as they are, I'm focusing on practicing low-level C++ programming with this project. I guarantee, though, were it for any other project, I would definitely opt for a more intuitive approach.

Thanks, guys!

Share this post


Link to post
Share on other sites
I also would have to sugest something more like

class matrix
{
int width, int height
double *storage;
public:
matrix ( int w, int h } : width(w), height(h) { storage = new double[width * height]; }
~matrix ( ) { delete[] storage; }
double get ( int x, int y ) { return storage[x + y*height]; }
void set ( int x, int y, double v ) { storage[x + y*height] = v; }
double *at ( int x, int y ) { return &storage[x+y*height]; }
};

Share this post


Link to post
Share on other sites
I would second the suggestion of a 2D interface to a 1D array, as KulSeran suggested. I would advise against the vector-of-vectors approach, because a vector-of-vectors is jagged, not rectangular.

Finally, consider boost::array or boost::multi_array. Your claims about wanting a "low level" approach make me suspicious; it sounds like you think doing things yourself in an ugly fashion would be "faster" than using an clean, sane interface, and this is most likely blatantly untrue; it's probably also destabilizing your program.

Share this post


Link to post
Share on other sites
Quote:
Original post by Agony
*** Source Snippet Removed ***


Your code potentially has alignment issues. Ideally, you should use ::operator new(size) to allocate your memory, and then place the array of doubles before the array of pointers to rows.

Share this post


Link to post
Share on other sites
Quote:
Original post by CrimsonMemory
I had considered both of your alternatives, and, as logical and good as they are, I'm focusing on practicing low-level C++ programming with this project. I guarantee, though, were it for any other project, I would definitely opt for a more intuitive approach.


I would argue you're not practicing low-level C++ programming, you're practicing low-level C programming.

If you wanted to be programming in C++, you would be using std::valarray for this stuff. If you really wanted to be doing low-level C++ programming, you would be specializing std::valarray.

--smw

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!