user3328918
user3328918

Reputation: 39

Pointer is NULL after returning from a function

I send int*** to a function and the function does it job, but when I try to use the pointer in outside after the function, it is NULL. Here is the function:

void pointerSort2(int* arr, unsigned int size, char ascend_flag, int*** pointers)
{
    int  i, j, *temp;
    int** sort=new int*[size];

    for (i=0;i<size;i++)
        sort[i]=&arr[i];                                                     

    if (ascend_flag==true)
    {
        for (i=0;i<size-1;i++)
        { 
            for(j=0; j<size-1-i;j++)
            {
                if (*sort[j]>*sort[j+1])
                {
                    temp=sort[j];
                    sort[j]=sort[j+1];
                    sort[j+1]=temp;
                }
        }
    }

    pointers=&sort;
}

When I try to use it after, the pointer is "0x000000 (???)"

Upvotes: 0

Views: 4510

Answers (3)

Zac Howland
Zac Howland

Reputation: 15872

First of, if this is not for an assignment, containers and algorithms already exist that will do all of this for you:

Containers: std::vector, std::list, std::deque Sort Algorithm: std::sort

Most of your problems go away simply by using the standard library templates.

That aside, you also do not appear to have a good understanding of the difference between pass-by-value and pass-by-reference as well as pointer semantics.

Passing an int*** to a function that takes an int***

If you declare a function as

void func(int i);

And call it:

int j = 0;
func(j);

Nothing that func does to the i parameter is reflected in j. A copy of j is passed to func. If you wanted to store any changes func made to the i parameter, you would need to either use a reference or a pointer:

void func(int& i);
// or
void func(int* pI); // requires you to call it via func(&j)

The same goes for your current code:

You've declared your sort function as follows

void pointerSort2(..., int*** pointers);

If you were to call it like so

int*** myPointer = NULL;
pointerSort2(..., myPointer);

You are passing it by value. This will copy the value of the pointer (currently NULL) into the function's local variable pointers. When the function returns, myPointer is unchanged. If your goal is to keep the changed value in myPointer, you need to either pass-by-reference or pass a pointer to your int*** (NOTE: this level of indirection is already a code smell!) The potential solutions to this would be:

void pointerSort2(..., int***& pointers);
// or
void pointerSort2(..., int**** pointers);

Which would allow you to call the function in these ways (respectively):

int*** myPointer = NULL;
pointerSort2(..., myPointer);
// or
pointerSort2(..., &myPointer);

For the first version, you would set the value of pointers to the value of sort like this:

pointers = sort;

Since pointers is a reference (an alias) to myPointer, the value of myPointer is changed.

For the second version, you would set the value of pointers to the value of sort like this:

*pointers = sort;

Since pointers is a pointer to the location of myPointer, you are setting the actual value of myPointer.

Note that in both cases, you are setting the value to sort (the value of the pointer), not &sort (the address of the pointer).

Side Note

bool is a type that is used for true and false values. Your ascend_flag parameter would be better served as a bool instead of a char.

Upvotes: 4

Chris Zhang
Chris Zhang

Reputation: 968

The following line:

pointers = &sort;

is causing your problem. sort is a pointer to a pointer. Being so, it is a variable that is created inside the local scope of the function.

It gets destroyed when the function exits.

Try removing the &

We want to go to the local pointers variable, find what it's pointing to, and change that value. pointers is not being passed by reference, it, like any other parameter, is copied and destroyed per each runtime function call on the stack.

*pointers = sort;

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

The function parameter int*** pointers is a local variable of the function. This variable will be destroyed after exiting the function.

I think that instead of line

pointers=&sort;

there should be

*pointers = sort;

Upvotes: 7

Related Questions