Kevin Lee
Kevin Lee

Reputation: 2347

Integer Pointer Array

I have started an introductory class to C. I cannot explain the output that I get from running the code below

./a.out 6

Output is:

Array A elements: 0 1 2 3 4 5 
Array B elements: 1 2 3 4 5 796830176

What I think the code is doing: When manup_array is executed, each value of the respective pointers will be incremented, but since it is post-fix, this takes effect only later on after the original value is returned.

True enough, when we print array A first, we get 0 1 2 3 4 5 (i.e. before incrementation). Subsequently when we print array B, the incrementation takes effect, so we get 1 2 3 [...]

What really puzzles me is why the last number is 796830176. Also, running this on various computers produces a different last number every time, suggesting that the pointer addressing is somehow responsible for this.

Could someone explain this to me?

Note: The outputs of each array are identical (1 2 3 4 5 6) if I use the pre-fix operator. This is consistent with what I think is going on -> the pointers don't change; only the values get updated.

#include <stdio.h>
#include <stdlib.h>

void manup_array(int *array[], int n); // Forward declaration.

int main(int argc, char *argv[])
{
    // The size N of 2 arrays are the same; obtain them from cmd line.
    int N = atoi(argv[1]); // Convert from str to int in C.

    int arrayA[N];  // Declare integer array.
    int *arrayB[N]; // Declare integer pointer array.

    for (int i = 0; i < N; i++)
    {
        arrayA[i] = i;
        arrayB[i] = &arrayA[i]; // Assign address of each element in A to element in B.
    }

    manup_array(arrayB, N);

    printf("Array A elements: ");
    for (int i = 0; i < N; i++)
    {
        printf("%d ", arrayA[i]);
    }

    printf("\n");

    printf("Array B elements: ");
    for (int i = 0; i < N; i++)
    {
        printf("%d ", *arrayB[i]);
    }

    printf("\n");

    return 0;
}

void manup_array(int *array[], int n) { // Take in B as input, then increase each elem by 1
    for (int i = 0; i < n; i++)
    {
        *array[i]++;
    }
}

Upvotes: 0

Views: 287

Answers (3)

Jeyaram
Jeyaram

Reputation: 9474

manup_array() increments the pointer, not the value as expected.

Modified manup_array().

void manup_array(int *array[], int n) { // Take in B as input, then increase each elem by 1
    for (int i = 0; i < n; i++)
    {
        //*array[i]++;
        (*array[i])++;
    }
}

I suggest to refer Pointer Arithmetic: ++*ptr or *ptr++?

Upvotes: 0

Mike McMahon
Mike McMahon

Reputation: 8574

void manup_array(int *arr[], int n) { // Take in B as input, then increase each elem by 1
    for (int i = 0; i < n; i++)
    {
        int val = (*arr[0]); // get the value pointed to by the current value of arr
        val++;               // increment it
        *(arr[0]) = val;     // assign it back
        arr++;               // increase the pointer
    }
}

Incredibly obtuse, but it demonstrates what you mean to do and how your obscure code muddled up the operators.

To add, makes debugging way easier!

Upvotes: 0

Lundin
Lundin

Reputation: 213318

This is really obscure code. What is does:

The function takes an array of pointers as parameter. Since the parameter to the function had type int *array[], any change of the items of array will affect the caller and alter arrayB.

The interesting part of the function is *array[i]++;. The operator precedence rules in C state that [] has higher prio than postfix ++, which has higher prio than unary *.

Since array is an array of pointers, array[i] gives you a pointer. Not a the value it points at. Then ++ increments the pointer to point at the next item in the arrayA of main.

And then finally there is a * which takes the contents of what that pointer pointed at, and then does nothing with them. The * is superfluous and just there to confuse the reader.

So back in main, you have changed all the pointers of arrayB. arrayB[0] now points at arrayA[1] and so on. The last item of arrayB will point one item past the end of arrayA, so for the last item, you access the array out-of-bounds and get a garbage value.

Upvotes: 1

Related Questions