• Advertisement
Sign in to follow this  

Double ** pointer parameter?

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

Hi everyone, i'm having some misunderstanding in the concept of double pointers as a parameter, as what i'd tried to achieve is to pass in a ** pointer as a parameter and store the value in a recursive call until the value reaches to a limit. i'd been running into the debugging and during the recursive calls, everything stores as it seems, however when it is quitting the loop, my pointers all gone into corruption and memory has been released, i'm wondering how the pointers gone. As it seems to be vry much different from a single * pointer parameter. Could anyone explain the mechanism of the structure? here's my snippet of code : void funcA(int ** ppT = NULL, int * pS = NULL){ int ** ppR = new int * [*pS]; for(int i = 0; i != *pS; i++) ppR = ppT; if(ppT != 0) delete [] ppT; ppT = new int * [*pS + 1]; // copy new buffer for(i = 0; i != (* pS); i++) ppT = ppR; ppT[* pS] = pS; (*pS)++; // store value of pS into ppT and stop at 3 if(*pS != 3) funcA(ppT, pS); } int main(){ int num = 0; int ** ppNum = NULL; // call funcA funcA(ppNum, &num); cout << ** ppNum << endl; } Thanks in advance, Rgrds, Daniel.

Share this post


Link to post
Share on other sites
Advertisement
Dear god that's bad code. Have you considered giving your variables meaningful names? I'm sure it would make it a lot easier to follow your logic. Additionally, I'd suggest using pointers a heck of a lot less. For instance, there you seem to be using them to grow a dynamic array. What are you trying to accomplish that std::vector doesn't offer you?

Share this post


Link to post
Share on other sites
You made ppR point to ppT. Naturally ppT is an array of empty pointers. You then DESTROY the data that ppT points to. ppR turns into an array of invalid references. You then reallocate ppT to point to ppR which doesn't point to anything anymore. In the end neither point to anything.

Edited for clarity.

Share this post


Link to post
Share on other sites
Quote:
Original post by kittycat768
You made ppR point to ppT.


No, he made the elements of ppR equal to the elements of ppT.
Quote:
Naturally ppT is an array of empty pointers. You then DESTROY the data that ppT points to. ppR turns into an array of invalid references. You then reallocate ppT to point to ppR which doesn't point to anything anymore. In the end neither point to anything.


All of that is incorrect for similar reasons.

Share this post


Link to post
Share on other sites
Quote:
Original post by kittycat768
You made ppR point to ppT. Naturally ppT is an array of empty pointers. You then DESTROY the data that ppT points to. ppR turns into an array of invalid references. You then reallocate ppT to point to ppR which doesn't point to anything anymore. In the end neither point to anything.

Edited for clarity.


Thanks for replying ;D,
but No, i'm sure ppT destroy doesn't affect ppR and reallocating ppT to ppR points to something. It only seems that after quitting the recursive call only then the ppT is destroyed and things corrupted, where my problem occurs.

Share this post


Link to post
Share on other sites
Quote:
Original post by kittycat768
You made ppR point to ppT. Naturally ppT is an array of empty pointers. You then DESTROY the data that ppT points to. ppR turns into an array of invalid references. You then reallocate ppT to point to ppR which doesn't point to anything anymore. In the end neither point to anything.

Edited for clarity.
No he doesn't. He copies ppT into ppR, so when he destroys ppT, ppR is still valid.

I'd say the problem is because you are double dereferencing ppNum in main(). You never allocate memory for the 1-D array (the int* inner array), but you try to dereference it. If you could edit your post and put your code in [source][/source] tags, it would help a lot.

[edit]

ninja'd++;

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Dear god that's bad code. Have you considered giving your variables meaningful names? I'm sure it would make it a lot easier to follow your logic. Additionally, I'd suggest using pointers a heck of a lot less. For instance, there you seem to be using them to grow a dynamic array. What are you trying to accomplish that std::vector doesn't offer you?


Thanks moderator,
I'm doing this for some purpose,
and this is just a simplified testing demo i'd made for debugging use,
so don mind bout the abbreviated form and meaningless names.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Dear god that's bad code.


This. You dereference several possibly NULL (hell, NULL by default) pointers without any sanity checks, leak the memory allocated for ppR every call, have magic numbers (Why is 3 the stopping point? What if *pS == 4 when the function is first called?), and have terribly hard to read variable names.

If I can follow your code, it looks like you are trying to add the numbers from *pS to 3 to the back of the array pointed at by ppT. There's no need to do this recursively, and no need to use all these pointers (even if you didn't want to use a std::vector, which would be the far more appropriate choice).

Share this post


Link to post
Share on other sites
Quote:
Original post by MikeTacular
Quote:
Original post by kittycat768
You made ppR point to ppT. Naturally ppT is an array of empty pointers. You then DESTROY the data that ppT points to. ppR turns into an array of invalid references. You then reallocate ppT to point to ppR which doesn't point to anything anymore. In the end neither point to anything.

Edited for clarity.
No he doesn't. He copies ppT into ppR, so when he destroys ppT, ppR is still valid.

I'd say the problem is because you are double dereferencing ppNum in main(). You never allocate memory for the 1-D array (the int* inner array), but you try to dereference it.

[edit]

ninja'd++;


yah mike, thanks it's what i'd come into mind as well,
but how'm i going to make the inner array exists after quitting the calls?
i'm guessing the inner one is declared as temporary and that's the reason why it ended up corrupting.

but my goal is trying to make this thing all happened within the call without out-of-scope manipulation of the size and declaration, question is, possible?

Share this post


Link to post
Share on other sites
Quote:
Original post by Driv3MeFar
Quote:
Original post by Sneftel
Dear god that's bad code.


This. You dereference several possibly NULL (hell, NULL by default) pointers without any sanity checks, leak the memory allocated for ppR every call, have magic numbers (Why is 3 the stopping point? What if *pS == 4 when the function is first called?), and have terribly hard to read variable names.

If I can follow your code, it looks like you are trying to add the numbers from *pS to 3 to the back of the array pointed at by ppT. There's no need to do this recursively, and no need to use all these pointers (even if you didn't want to use a std::vector, which would be the far more appropriate choice).


Thanks for advice,
as i had claimed,
i'm doing this for some purpose,
don't ask about why and don't concern about the magic number,
it corrupts when *pS == 4 when function is first called,
those are not of my concern,
as i had claimed,
i'm simplifying this all and just try to figure out what happens with the double ** pointer,
the magic number is not of my concern.

Share this post


Link to post
Share on other sites
Quote:
Original post by danong
but my goal is trying to make this thing all happened within the call without out-of-scope manipulation of the size and declaration, question is, possible?


What, exactly, is "this thing" you are trying to make happen?

Share this post


Link to post
Share on other sites
Your recursive function "works", as long as by "works" you mean "doesn't crash". Each time through the function creates two arrays and destroys one, and the value of ppNum (from main()) never changes. How could it? You pass it into a function and otherwise do not change it. Function arguments in C/C++ are passed by value, not by reference... even if they happen to be pointers. Or even pointers to pointers.

Share this post


Link to post
Share on other sites
Quote:
Original post by danong
but how'm i going to make the inner array exists after quitting the calls?
i'm guessing the inner one is declared as temporary and that's the reason why it ended up corrupting.
Sorry, I honestly have no clue what you're saying here.

Quote:
Original post by danong
but my goal is trying to make this thing all happened within the call without out-of-scope manipulation of the size and declaration, question is, possible?
Or here.

Quote:
Original post by danong
i'm doing this for some purpose,
don't ask about why and don't concern about the magic number,
Is this homework? I'm sorry, but I'm not willing to help someone who won't let me help them. And I won't do someone's homework. I've got my own to do.

Share this post


Link to post
Share on other sites
Quote:
Original post by danong
this is just a simplified testing demo i'd made for debugging use
So your actual code is more complicated and less debuggable than all that? I think, if you're willing to tell us the objective here, that we can demonstrate a safe way to do the same thing.

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Your recursive function "works", as long as by "works" you mean "doesn't crash".


Am I missing something, or won't the first copy loop crash (probably, although technically the behavior would be undefined) when it derefences ppT?

Quote:

for(int i = 0; i != *pS; i++)
ppR = ppT; //<---ppT == NULL

Share this post


Link to post
Share on other sites
Quote:
Original post by MikeTacular
Quote:
Original post by kittycat768
You made ppR point to ppT. Naturally ppT is an array of empty pointers. You then DESTROY the data that ppT points to. ppR turns into an array of invalid references. You then reallocate ppT to point to ppR which doesn't point to anything anymore. In the end neither point to anything.

Edited for clarity.
No he doesn't. He copies ppT into ppR, so when he destroys ppT, ppR is still valid.

I'd say the problem is because you are double dereferencing ppNum in main(). You never allocate memory for the 1-D array (the int* inner array), but you try to dereference it. If you could edit your post and put your code in [source][/source] tags, it would help a lot.

[edit]

ninja'd++;


Thanks mike,
i'd fixed the problem,
just as what you'd said.
you're helpful ;)

Thanks everyone,
God bless,

Regards,
Daniel.

Share this post


Link to post
Share on other sites
Quote:
Original post by Driv3MeFar
Quote:
Original post by Sneftel
Your recursive function "works", as long as by "works" you mean "doesn't crash".


Am I missing something, or won't the first copy loop crash (probably, although technically the behavior would be undefined) when it derefences ppT?

Quote:

for(int i = 0; i != *pS; i++)
ppR = ppT; //<---ppT == NULL

Ah, and how many times does the body of that for-loop execute?

Share this post


Link to post
Share on other sites
Quote:
Original post by danong
Thanks mike,
i'd fixed the problem,
just as what you'd said.
you're helpful ;)

Thanks everyone,
God bless,

Regards,
Daniel.
You're welcome, but please take into consideration everyone else's posts too. They pointed out some crucial bugs that I missed. Especially when you leak ppR's memory (as pointed out by Driv3MeFar).

Share this post


Link to post
Share on other sites
Some one please explain to me how ppR (an array of POINTERS) doesn't become an array of dangling references once he calls "delete[] ppT."

Share this post


Link to post
Share on other sites
Quote:
Original post by Sneftel
Ah, and how many times does the body of that for-loop execute?


Durr, should've caught that... [embarrass]

Share this post


Link to post
Share on other sites
Quote:
Original post by kittycat768
Some one please explain to me how ppR (an array of POINTERS) doesn't become an array of dangling references once he calls "delete[] ppT."
If he said ppR = ppT, then yes, it would become invalid when delete [] ppT is called. However, he loops through each element in ppT and copies each element into ppR.

Share this post


Link to post
Share on other sites
Quote:
Original post by MikeTacular
Quote:
Original post by danong
but how'm i going to make the inner array exists after quitting the calls?
i'm guessing the inner one is declared as temporary and that's the reason why it ended up corrupting.
Sorry, I honestly have no clue what you're saying here.

Quote:
Original post by danong
but my goal is trying to make this thing all happened within the call without out-of-scope manipulation of the size and declaration, question is, possible?
Or here.

Quote:
Original post by danong
i'm doing this for some purpose,
don't ask about why and don't concern about the magic number,
Is this homework? I'm sorry, but I'm not willing to help someone who won't let me help them. And I won't do someone's homework. I've got my own to do.


not homework,
just designing some components for robotic simulation.
actually i need a pointers for the components and overloading some operators, and the reason i don prefer vector is because when i'm doing some comparison or other operator calls, std::vector doesn't match my need,
i'm doing everything from scratch,
just my own interest,

no offense,
i only wan to know what happen with the double ** pointer.

Share this post


Link to post
Share on other sites
Driv3MeFar : i'm actually wanting to traverse all nodes from a root in a tree structure and store all of them.

Sneftel : for my original one, it stopped when all nodes (or rather all children of nodes) had been traversed.

dmatter :
alright, here's my original code.



template <class T>
void Tree<T>::traverseAllNodes(TreeNode<T> ** ppAllNodes, TreeNode<T> * pNode){
// traverse all tree nodes and store them

// reset size of nodes
if(pNode == _root)
_size = 0;

// copy old memory buffer
TreeNode<T> ** ppTemp = new TreeNode<T> * [_size];
for(int i = 0; i != _size; i++)
ppTemp = ppAllNodes;

// reallocate new memory buffer
if(ppAllNodes != NULL)
delete [] ppAllNodes;

ppAllNodes = new TreeNode<T> * [_size + 1];

// assign new memory buffer
for(i = 0; i != _size; i++)
ppAllNodes = ppTemp;

ppAllNodes[_size] = pNode;

// clear memory buffer
delete [] ppTemp;

// increase size
_size++;

// traverse to child node
for(i = 0; i != pNode->getChildSize(); i++)
traverseAllNodes(ppAllNodes, pNode->getChild(i));

};

Share this post


Link to post
Share on other sites
Quote:
Original post by kittycat768
Some one please explain to me how ppR (an array of POINTERS) doesn't become an array of dangling references once he calls "delete[] ppT."


int a[] = {1,2,3};
int b[] = {4,5,6};

int ** pA = new int*[2];
pA[0] = a;
pA[1] = b;

// so far so good

delete [] pA;

cout << a[1]; // it's still there!!!

Share this post


Link to post
Share on other sites
Quote:
Original post by MikeTacular
Quote:
Original post by kittycat768
Some one please explain to me how ppR (an array of POINTERS) doesn't become an array of dangling references once he calls "delete[] ppT."
If he said ppR = ppT, then yes, it would become invalid when delete [] ppT is called. However, he loops through each element in ppT and copies each element into ppR.


So, you're saying that BECAUSE it's an allocated array of pointers that the data gets copied rather than just setting a bunch of pointers? I'm not sure I can believe that since each element is an unallocated pointer. One part of me agrees with you and another part of me tells me to completely avoid this type of code behavior to begin with.

Share this post


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

  • Advertisement