# Question regarding deleting pointers to matrices

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

## 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 on other sites
Every new call needs a matching delete, so it would be the latter, followed by the former.

##### Share on other sites
Ah, that's sort of what I expected. Thanks a lot!

##### Share on other sites
It's also worth noting that the whole issue could be avoided with a std::vector< std::vector< double > >.

##### Share on other sites
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 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 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 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 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 on other sites
Quote:
 Original post by CrimsonMemoryI 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 on other sites
Quote:
 Original post by BregmaI 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

and I would argue that since "new" and "delete" aren't C that his code is distinctly C++.

##### Share on other sites
Quote:
 Original post by linternetand I would argue that since "new" isn't C that his code is distinctly C++.

He uses "new" instead of "malloc" and "delete" instead of "free". Hardly deserving of a distinctly epithet, if you ask me. In fact, what he wrote is C code which requires a C++ compiler to compile. Just like IOCCC entries are not representative of a sane C program.

##### Share on other sites
Quote:
 Original post by ToohrVykHe uses "new" instead of "malloc" and "delete" instead of "free". Hardly deserving of a distinctly epithet, if you ask me. In fact, what he wrote is C code which requires a C++ compiler to compile. Just like IOCCC entries are not representative of a sane C program.

Point taken. I just don't understand why the community constantly denigrates perfectly legal, working code simply because it doesn't adhere to the academic dogma of a language.

##### Share on other sites
Quote:
Original post by linternet
Quote:
 Original post by ToohrVykHe uses "new" instead of "malloc" and "delete" instead of "free". Hardly deserving of a distinctly epithet, if you ask me. In fact, what he wrote is C code which requires a C++ compiler to compile. Just like IOCCC entries are not representative of a sane C program.

Point taken. I just don't understand why the community constantly denigrates perfectly legal, working code simply because it doesn't adhere to the academic dogma of a language.

Because it can create silly situations. Consider a 100KLOC project written in C, but C++-compilable, with a header file included almost everywhere. Add an #include <vector> at the top of that one header file. The one hundred thousand lines of C code have automagically turned into C++.

Because of this, most people use the name "C++" to refer to modern C++, to distinguish it from C-compiled-as-C++. The main idea behind this is that (modern) C++ code is more easily exception-safe, interacts better with the standard library, requires less non-default constructors and destructors, and generally requires less work than the C-like version. It is not so much academic dogma as it is using the language to its full extent, doing less work to write faster and more easily maintainable programs.

##### Share on other sites
Quote:
 Original post by ToohrVykBecause it can create silly situations. Consider a 100KLOC project written in C, but C++-compilable, with a header file included almost everywhere. Add an #include at the top of that one header file. The one hundred thousand lines of C code have automagically turned into C++. Because of this, most people use the name "C++" to refer to modern C++, to distinguish it from C-compiled-as-C++. The main idea behind this is that (modern) C++ code is more easily exception-safe, interacts better with the standard library, requires less non-default constructors and destructors, and generally requires less work than the C-like version. It is not so much academic dogma as it is using the language to its full extent, doing less work to write faster and more easily maintainable programs.

Understood and well explained.

The only thing I'll mention is that when working with old code and people whose skills are out of date (me) the practical application of purley modern C++ becomes nearly impossible.

I'm about as stubborn as they come and even I've seen the benefits of using std::string, and std::vector. If however(as a stupid example) I need faster-than-linear searching and am not quite ready to use std::map, I can put c_st()'s into a 10+ year old "C-style" hash class without losing the time it would take to figure map out.

That mixing is why a language that is (to use your signature) "an octopus made by nailing extra legs onto a dog" is so popular in the first place.

##### Share on other sites
Quote:
 Original post by linternetThe only thing I'll mention is that when working with old code and people whose skills are out of date (me) the practical application of purley modern C++ becomes nearly impossible.

I agree. If all you know C, writing applications in modern C++ is a nigh impossible task, and a C++ compiler becomes little more than a C compiler upgrade.

Quote:
 That mixing is why a language that is (to use your signature) "an octopus made by nailing extra legs onto a dog" is so popular in the first place.

Quite sadly, yes, that's true. Sadly, few people realize that they're abandoning the simplicity of C without gaining the advantages of C++. The two languages, contrary to populary belief, interact together extremely badly.

##### Share on other sites
Quote:
 Quite sadly, yes, that's true. Sadly, few people realize that they're abandoning the simplicity of C without gaining the advantages of C++. The two languages, contrary to populary belief, interact together extremely badly.

You're basically saying that pre-standardized C++ is/was useless?

##### Share on other sites
Quote:
Original post by linternet
Quote:
 Quite sadly, yes, that's true. Sadly, few people realize that they're abandoning the simplicity of C without gaining the advantages of C++. The two languages, contrary to populary belief, interact together extremely badly.

You're basically saying that pre-standardized C++ is/was useless?

It was a prototype, in many ways.

However, there were still advantages available to be gained - in particular, constructors and destructors for classes, and language support for polymorphism - that are only gained if you seek them.