Jump to content
  • Advertisement
Sign in to follow this  
Zekeva

Deallocating a 2D array

This topic is 4402 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

The following C++ code dynamically creates a 2D array of size m by n:
int** array = new int*[m];
for (int i=0;i<m;i++)
  array = new int[n];
My question is: to deallocate this array is it sufficient to go 'delete array' or do I need to go:
for (int i=0;i<m;i++)
  delete array;
delete array;
Cheers

Share this post


Link to post
Share on other sites
Advertisement
You need to do the latter. But you really shouldn't be doing it like this in C++ anyway, as there are better alternatives.

I think there's a thread going in General Programming on multidimensional array management; you might check it out.

Share this post


Link to post
Share on other sites
Deallocation must be symmetric, at run-time, to allocation. You must delete what you new, delete[] what you new[], and free() what you malloc() (although you shouldn't be doing that in C++ normally). That applies to every allocation, not just "parent" allocations. There is no reference counting magic or anything along those lines happening by default: In C++, you don't pay for what you don't ask for, but you don't get it, either.

Also, you have to make sure that for each allocation, the deallocation happens exactly once. This can be tricky business, especially if (as is very often desirable) you have multiple things pointing to the same allocation.

This is why, in C++, we try to make use of the 'Resource Acquisition Is Initialization' idiom: generally, wrap allocations into constructors and deallocations into destructors, so you can't forget the deallocation. Of course, the simplest approach there only covers the case where the object "owns" the allocated memory.

For completeness' sake, that approach looks like this:


class Foo {
Bar* myAllocation;
Foo() : myAllocation(new Bar()) {}
Foo(const Foo& other) : myAllocation(new Bar(*(other.myAllocation))) {}
Foo& operator=(const Foo& rhs) {
Foo other(rhs);
std::swap(myAllocation, other.myAllocation);
return *this;
}
~Foo() { delete myAllocation; }
}


Now when a Foo is copy-constructed, the Bar is "cloned" (note that this does not respect polymorphism, because you requested a new Bar, not a new type-of-thing-pointed-at-by-other-dot-myAllocation - sadly, C++ constructors aren't virtual, so you have to hack that kind of thing if you need it), with the pointer set to point at a newly allocated Bar which is a copy of the old one. When a Foo is default-constructed, the Bar is allocated and default-constructed. When a Foo destructs, the Bar is properly deallocated. The only complicated case is the assignment operator: when one Foo is assigned to another, what happens is that we copy-construct a temporary Foo, and then swap the pointers around so that the temporary Foo takes ownership of the current object's "old" Bar, and the current object takes ownership of the copied Bar. Finally, at the end of the function, the temporary Foo falls out of scope, so its destructor is called - deallocating the old Bar. This "copy-and-swap idiom" implicitly guards against self-assignment and also helps provide exception safety.

Anyway, in more complicated situations, we don't reinvent the wheel, but use library components. The standard library isn't much help here, but Boost provides several excellent tools, including boost::shared_ptr.

But then, the real problem here wasn't about memory management, but about creating a multi-dimensional array ;) So I will tell you again to look at Boost (in particular boost::multi_array), and also read this.

Share this post


Link to post
Share on other sites
Appreciate the help everyone. The concept of a vector of pointers to vectors of T is something I considered and, whilst it's kind of complicated and messy to code, it's certainly a lot safer than a primitive array. And I'll look into the boost classes as well. Thanks again.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!