Home > Mobile >  Question about how pointers work in C with a problem
Question about how pointers work in C with a problem

Time:10-19

I'm solving a problem for class in C where I return the biggest value from an unsorted array and the index of that value gets stored in the pointer index_ptr.

Here is the code I built:

int get_biggest_index(int array[], size_t array_size, int *index_ptr){
    int max = array[0], index;
    for (int i = 0; i < array_size-1; i  ){
        if (array[i 1] > max){
            max = array[i];
            index = i;
        }
    }
    index_ptr = &index;
    printf("idx: %d\n", *index_ptr); //purely for testing
    return max;
}

I know the above works as intended for returning the highest value, but running it in this context:

int main() {
    int arr[5] = {4, 7, 3, 9, 5};
    size_t arr_size = 5;
    int *idx;
    printf("biggest value in array arr => %d\n", get_biggest_index(arr, arr_size, idx));
    printf("idx of biggest value => %d", *idx);
    return 0;
}

The output is:

idx: 3
max value in array arr => 9
idx of max value => -98693133

Can someone explain me specifically why this is happening in regards to the value of the pointer and how to fix it?

I'll also be happy to listen to any other suggestions regarding the rest of the code as I'm sure it can be better.

Thank you very much for the help!

CodePudding user response:

The variable index is local inside the get_biggest_index function. Its life-time will end when the function returns, and any pointer to it will become invalid.

Although that's not the problem here since index_ptr is also a local variable, whose value will be lost when its life-time ends as the function returns.

The problem is that you misunderstand how emulating pass-by-reference works in C. You should not pass a pointer, and make it point to a variable in the function. Instead you should use the pointer-to operator & in the call to pass a pointer to an existing variable. And then in the function dereference the pointer to set the original variables value.

Something like this:

int get_biggest_index(int array[], size_t array_size, int *index_ptr){
    int index;

    // ...

    *index_ptr = index;  // Set the *value*

    // ...
}

And call it as:

int idx;  // Not a pointer
get_biggest_index(arr, arr_size, &idx);  // Pass pointer to the idx variable

CodePudding user response:

You should assign to index_ptr the value of the index and not the address of the index. You should replace index_ptr = &index; with *index_ptr = index in line 8. Think of a pointer to be a bucket. If you put * before it, you will access the content of the bucket.

In your particular case, you send the bucket to a function, and you want to fill it with the index of the biggest number. When you do index_ptr = &index; you are replacing the original bucket with another one and leave the original bucket empty.

The right code should be:

int get_biggest_index(int array[], size_t array_size, int *index_ptr){
    int max = array[0], index;
    for (int i = 0; i < array_size-1; i  ){
        if (array[i 1] > max){
            max = array[i];
            index = i;
        }
    }
    *index_ptr = index; // this is correct
    printf("idx: %d\n", *index_ptr); //purely for testing
    return max;
}

CodePudding user response:

int *index_ptr is a local variable to the function. It doesn't get returned to the caller, so index_ptr = &index; does nothing meaningful. Also, you can't have a returned pointer point at the address of a local variable, because local variables go out of scope when the function finishes.

A more sensible function would be this:

int* get_biggest_index (size_t size, int array[size]){
    int* result = NULL;
    int max = INT_MIN;
    for (int i = 0; i<size; i  ){
        if (array[i] > max){
            max = array[i];
            result = &array[i];
        }
    }

    return result;
}

This doesn't access the array out of bounds in case size is zero. It returns NULL upon error, otherwise a pointer to the largest item. It points into the passed array, so it doesn't refer to a local variable. The returned pointer is copied by value to the caller.

CodePudding user response:

For indexes use size_t type (not int). Be consistent.

int get_biggest_index(int *array, size_t array_size, size_t *index_ptr){
    int max = array[0];
    *index_ptr = 0;
    for (size_t i = 1; i < array_size; i  ){
        if (array[i] > array[*index_ptr]){
            *index_ptr = i;
        }
    }
    printf("idx: %zu\n", *index_ptr); //purely for testing
    return array[*index_ptr];
}
  • Related