Ofek .T.
Ofek .T.

Reputation: 762

pointer won't go back to it's reference from a function after return (stays null) C++

im using my own linked list made with stuct. The struct has 2 ints and 1 pointer to another struct, next.

I'm using the LL (linked list) but in one of the functions a certain pointer won't change.

AddChain( &MakeChain(..values..), added )

this is how i call the function, i send her a new chain to link to the big one, and if there is no big one aka it's NULL so it will replace it. In this call added is a NULL ptr to a chain struct.

void AddChain(PolyChain* pol, PolyChain* main) // adds the new piece to the chain
{
    PolyChain *current = main, *back = NULL;

    if (main == NULL)
    {
        pol->next = NULL;
        main = pol;
        return;
    }
... \\ there is continuation of the function but it wont get so far without main one
}

Now, as you can see if the main chain is a NULL I make to to reference to the same thing as the new chain I got. I'm running in the debugger and pol HAS a value and after the line:

main = pol;

main realy changes to point to what pol is pointing to. BUT after the return in AddChain, added which is the main in AddChain is still a NULL. It didn't get the value back from the function, it didn't change the pointer of added as like it was by value and not by reference, but it was by reference.

What's causing this problem?

EDIT: MakeChain returns a PolyChain and AddChain gets PolyChain*, this is why i used &.

Upvotes: 2

Views: 133

Answers (4)

Mykola
Mykola

Reputation: 3363

You must use pointer to pointer to modify pointer value inside the function

void AddChain(PolyChain* pol, PolyChain** main)

than in your code:

void AddChain(PolyChain* pol, PolyChain** main) // adds the new piece to the chain
{
    PolyChain *current = *main, *back = NULL;

    if (main == NULL)
    {
        pol->next = NULL;
        *main = pol;
        return;
    }
... \\ there is continuation of the function but it wont get so far without main one
}

to pass value to the function just call

AddChain(pol, &main);

where pol and main are regular pointers to PolyChain type.

or with simple values:

PolyChain* pMain = &main;
AddChain(&pol, &pMain);

NOTE: This practics are extremaly error prone so you must be extra careful for managing pointers at this manner.

Upvotes: 1

maddin45
maddin45

Reputation: 747

You are changing a copy of the pointer, since you are passing the pointer by value. If you want to change the pointer that comes from the calling scope you will have to pass a pointer to the pointer or a reference to the pointer:

void AddChain(PolyChain*& pol, PolyChain*& main) {...}

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

This happens because you pass your pointer PolyChain* main by value. A simple way of visualizing "passing by value" is to think about it as "passing by copy": a copy of the pointer is made specifically for the call of AddChain. That is why any change to the pointer inside AddChain remains local to AddChain.

You could fix this problem in three different ways:

  • Take PolyChain*& main by reference - this is the simplest solution. because nothing else needs to change.
  • Take PolyChain** main by pointer - in this case AddChain needs to dererefence main, i.e. use *main instead of main, and take a pointer when passing main to AddChain
  • Return PolyChain* with the new value of main - in this case the caller must make an assignment of the result back to the pointer passed for main.

Upvotes: 3

JSF
JSF

Reputation: 5321

void AddChain(PolyChain* pol, PolyChain* main)
...
        main = pol;
        return;

In that code, main is a local copy of whatever pointer was passed in, so assigning to main has no effect on the pointer outside the function.

You didn't give enough information for me to deduce your intent, so it is likely (but not clear) that you could fix the problem by passing the pointer by reference:

void AddChain(PolyChain* pol, PolyChain*& main)

Upvotes: 2

Related Questions