Array of pointers not changing out of scope?

I have a PiggyBank class that stores "Coins" with the functions DropIn and GrabOut. The functions will store a pointer to the "Coins" in an growable array of pointers. (CoinStorage**) The functions look like this:

DropIn is passed the array address, size, and a pointer to the coin that is supposed to be "Dropped In".
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bool PiggyBank::DropIn(Coin** coinStorage, int& size, Coin* coin) {
	Coin** temp = 0;
	temp = new Coin* [size+1];
	if(!temp)
		return false;

	for(int x=0; x<size; x++)
		temp[x] = coinStorage[x];
	temp[size] = coin;
	size++;

	if(coinStorage)
		delete [] coinStorage;
	coinStorage = temp;
	return true;
}


GrabOut is passed the array address and size, makes a copy of the passed array of pointers with size-1, and returns the Coin* that was "removed" from the array.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Coin* PiggyBank::GrabOut(Coin** coinStorage, int& size) {
	if(size) {
		Coin* save = coinStorage[size-1];
		Coin** temp = new Coin* [size-1];

		for(int x=0; x<size-1; x++)
			temp[x] = coinStorage[x]; 
		size--;

		if(coinStorage)
			delete [] coinStorage;
		coinStorage = temp;
		return save;
	}
	else {
		cerr << "GrabOut(): No coins to grab!\n";
		return 0;
	}
}


My problem is that it appears as though the functions are not actually changing coinStorage "out of scope", because when I call DropIn() twice, on the second call, I assumed that the value from the first call should be in coinStorage[0], but it is not. What am I missing here?

One solution was for me to modify DropIn() to return temp** instead of a bool, and have the storage = the returned ** outside of the function.. but I'm still curious why my original method didn't work.

Thanks in advance for any help!
Last edited on
DropIn() deletes the coinStorage array and doesn't replace it with temp, so there can't be anything in there after the call.

Is there any reason you're not using a std::vector?
We were supposed to make our own growable array. (this is an exercise)

For some reason the code on here has written storage = temp, but my code is coinStorage = temp, which is what I meant to put here. Is this what you were referring to? (I edited it now, not sure how that happened but sorry nonetheless)

Either way, the code still breaks on the second function call on the first iteration of this loop in DropIn():
1
2
	for(int x=0; x<size-1; x++)
	    temp[x] = coinStorage[x]; 



You need to change your function definition from

bool PiggyBank::DropIn(Coin** coinStorage, int& size, Coin* coin)

to

bool PiggyBank::DropIn(Coin**& coinStorage, int& size, Coin* coin)

I added & after Coin**. This is read right to left, so it is a reference to a pointer of an array of pointers. When you allocate memory within a method that you want to assign to one of the parameters you need to pass in the address of the variable you are assigning allocated memory too. Adding & will do this for you.
LaffyTaffy wrote:
For some reason the code on here has written storage = temp, but my code is coinStorage = temp, which is what I meant to put here. Is this what you were referring to?

Yes it was. I'm not sure, but I think what might be happening is that delete[] coinStorage; is destroying the objects pointed to by coinStorage, which are the same ones pointed to by temp. So you should be getting an array whose size is correct, but whose pointers point to garbage values.

I'd step through it with the debugger to really be sure of what's going on.

@binarybob350: pointers and references are basically different ways of achieving the same thing.
@binarybob350: pointers and references are basically different ways of achieving the same thing.


No, binarybob has it right. Basically what LaffyTaffy is trying to achieve is having a modifyable 2D array (a modifyable Coin**), which would require another pointer or a reference (much easier to use in this case, since you already have a bunch of pointers here). With just a Coin**, you can only modify the sub-arrays, not the first array, which is what LaffyTaffy wants.
I never would have guessed. Thanks for the correction.
Also you're making a little mistake here.
1
2
3
4
temp = new Coin* [size+1];
	if(!temp)
		return false;

from "http://www.cplusplus.com/reference/std/new/operatornew[]/"
new[] on failure, it throws a bad_alloc exception.

You need to use temp = new (nothrow) Coin* [size+1];
Topic archived. No new replies allowed.