Question about dynamic 2D array using ScopedPointer


#1

I’ve been using nested ScopedPointers to implement a 2D array of doubles.

[code]ScopedPointer<ScopedPointer> myArray;

// 2D array first dimension ‘x’, second dimension 'y’
myArray = new ScopedPointer[x];
for (int i=0; i<x; i++)
{
myArray[i] = new double[h];
for (int j=0; j<y; j++)
{
myArray[i][j] = 0;
}
}[/code]

I now want to dynamically re-size the array. The only way I’ve successfully been able to achieve that is to call myArray.release() before re-initialising.

Now, the class documentation for ScopedPointer clearly states that release() doesn’t cause the object to be deleted - but if I call release() without assigning the result to a variable, does that mean the object disappears and the memory gets deallocated anyway?

Thanks in advance,
Andrew


#2

why on earth are you trying to make an array using scoped pointer? An OwnedArray is effectively an array of scopedpointers anyway


#3

Good question, I guess I’m just trying to understand ScopedPointers as best I can. If you’ve seen my other noobish post, you will have noticed I’ve been playing with OwnedArrays as well.


#4

why not easier

and accessing the values like this

but be sure that x is not beyond the range

or does somebody have a better solution for dynamic 2D Arrays (would be interesting to know)


#5

Thanks chkn, but I’ve got to say that looks a little bit ugly! :wink:

Anyhow I’ve played around with this in a separate class for so long I had forgotten that ultimately I need the inner array to interface with a function which requires a standard (i.e. pointer based) array of doubles. So the inner array needs to be either double* or ScopedPointer.


#6

I would probably suggest looking at HeapBlock


#7

In the absence of a proper Array2D class, OwnedArray <HeapBlock > would probably be the best plan.


#8

Thanks gurus, I’ll take a look at HeapBlock now.

Still no comment on my original question about releasing ScopedPointer<ScopedPointer>?? It actually seems to work OK.


#9

Seriously, embedding scopedpointers is not clever. If you find yourself typing “new ScopedPointer”, then you’ve gone way off track!


#10

Jules BTW as suggestion:

would be great to have something like an InfiniteArray, if you index is out of range it gives you a default value back.

Example:
InfitiveArray array;
array.setDefaultValue(42);

array[20]=30;
array[500]=123;

array[499] // is 42
array[500] // is 123
array[650] // is 42

val=


#11

Doesn’t really sound very useful to me… Wouldn’t SparseSet be able to do a similar job?


#12

OK I get the message - I guess I just feel that if I could understand what was going on with release() then I might fully understand why it’s a poor approach. Then again, there might be some other stuff I’m not comprehending which is of greater significance :roll:

BTW, I never imagined I’d find myself wishing that I could use pointers to solve something. The irony is almost overwhelming!


#13

ScopedPointers are designed for objects, not arrays - it calls ‘delete’, not ‘delete[]’, so if you make one point to an allocated array, it won’t be deleted correctly.


#14

jules: not really, in an InfinityArray the position of a value is fixed and part of the information you store (which can be any type not just integer) like a BigInteger, anyway i have my own implementation for that…


#15

Aha, I wondered about that when I implemented it with ordinary pointers (just for kicks).

Am now having problems with the OwnedArray<HeapBlock> approach leaking objects though. I’ll try and figure it out myself, but will post back here if I get stuck.


#16

So without trying any dynamic resizing, the following works fine until termination. To pass the double[] as an argument to the other function, I just use myArray[i]->getData().

[code]OwnedArray<HeapBlock> myArray;

// 2D array first dimension ‘x’, second dimension 'y’
for (int i=0; i<x; i++)
{
myArray.add(new HeapBlock(y));
for (int j=0; j<y; j++)
{
myArray[i]->getData()[j] = 0;
}
}[/code]
At termination, I’m getting leaked objects detected. I’ve tried a number of variations on a theme in the destructor for the containing class (including doing nothing), but to no avail.

for (int i=0; i<x; i++) { myArray[i]->free(); //myArray[i]->~HeapBlock(); } myArray.clear(true); //myArray.~OwnedArray();

BTW, thanks all for the advice so far - I hope I’m not causing too much annoyance.


#17

A HeapBlock destroys its allocated memory automatically; that is its purpose. The same goes for an OwnedArray. Therefore, when your outer array is destroyed, all its owned HeapBlock objects will automatically be destroyed, which will in turn destroy all the allocated double arrays.

This is your problem:

OwnedArray<HeapBlock<double>> myArray;

// 2D array first dimension 'x', second dimension 'y'
myArray = new OwnedArray<HeapBlock<double>>;

You’re using a stack instance myArray, but you’re trying to assign it a newly instantiated OwnedArray. Does that even compile?

OwnedArray<HeapBlock<double>> myArray;

// ... 

for (int i=0; i<x; i++)
{
   myArray.add(new HeapBlock<double>(y));
   for (int j=0; j<y; j++)
   {
      myArray[i]->getData()[j] = 0;
   }
}

that should be all you need…

And to clear it all, all you’d need to do is myArray.clear()
[although, if it’s a member of some other class, that’s not even strictly necessary either, as the array will automatically clear itself on destruction]


#18

Sorry, that was a typo that I made when sanitising variable names in my code example. I actually edited the post to fix it, but I guess you’d pounced already!

I’ve double checked and I am doing everything as you say, but am still getting the leaks.


#19

[quote=“haydxn”]A HeapBlock destroys its allocated memory automatically; that is its purpose. The same goes for an OwnedArray. Therefore, when your outer array is destroyed, all its owned HeapBlock objects will automatically be destroyed, which will in turn destroy all the allocated double arrays.

And to clear it all, all you’d need to do is myArray.clear()
[although, if it’s a member of some other class, that’s not even strictly necessary either, as the array will automatically clear itself on destruction][/quote]

That is what I was expecting - only problem is that I’ve sprung a leak. I’ve even rolled back to a different implementation to verify I haven’t introduced a leak somewhere else.


#20

Okay, I just tried running this exact code:

	OwnedArray<HeapBlock<double>> myArray;

	// ... 
	int x = 20;
	int y = 100;
	for (int i=0; i<x; i++)
	{
		myArray.add(new HeapBlock<double>(y));
		for (int j=0; j<y; j++)
		{
			myArray[i]->getData()[j] = 0;
		}
	}

	myArray.clear ();

and it doesn’t leak anything; if you’re getting leaks, either your posted code isn’t as accurate as your say, or you’re leaking from somewhere else entirely.