Home > Software design >  Why can't a pointer's value be accessed with square bracket syntax when returned from a fu
Why can't a pointer's value be accessed with square bracket syntax when returned from a fu

Time:10-08

I am learning basic C, and I am still trying to understand arrays and pointers. I am trying to write a push function to mimic the behavior of an array in Javascript, but with a workaround, since arrays cannot be returned in C.

When I access the returned pointer with (*p 3), it yields the correct value, but p[3] does not. However, I can still access the correct value within push() with p[3]. Why is this?

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

void br() {
    putchar('\n');
}

int *push(int *arr, size_t size, int val) { 
    int *arr2 = calloc(size   1, sizeof(int));
    for (int i = 0; i < size; i  ) {
        arr2[i] = arr[i];
    }
    arr2[size] = val;
    return arr2;
}

int main(int argc, char *argv[]) {
    int myNums[] = { 1, 2, 3 };

    int *p = push(myNums, sizeof(myNums), 4);
    printf("%i", (*p   3));
    br();
    printf("%i", p[3]);
    br();

    return 0;
}

EDIT: I think there is a better solution using structs.

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


typedef struct{
    int*values;
    int length;
} intArray;

void printInts(intArray * arr){
    for(int i = 0; i < arr->length; i  ){
        printf("Value %i: %i\n",i,arr->values[i]);
    }
}

intArray push(intArray * arr, int value){
    arr->length  ;
    arr->values = realloc(arr->values, sizeof(int)*arr->length);
    arr->values[arr->length-1] = value;
    return *arr;
}

intArray pop(intArray * arr){
    arr->length--;
    arr->values = realloc(arr->values, sizeof(int)*arr->length);
    return *arr;
}

int main(int argc, char *argv[]) {
    intArray myNums;
    myNums = push(&myNums,15);
    myNums = push(&myNums,30);
    myNums = push(&myNums,45);
    myNums = push(&myNums,60);
    myNums = pop(&myNums);

    printInts(&myNums);

    /* expected output:
    Value 0: 15
    Value 1: 30
    Value 2: 45
    */

    return 0;
}

CodePudding user response:

There are two mistakes in the code:

  • int *p = push(myNums, sizeof(myNums), 4);

    sizeof(myNums) is not the length of the array (ie: the number of elements), but its size in bytes.

    You can use sizeof(myNums) / sizeof(myNums[0]) to compute the number of elements at compile time.

  • printf("%i", (*p 3));

    You first print *p 3, which is not the same as *(p 3): you get the expected output only by coincidence because *p, which is equivalent to p[0] happens to have the value 1. Conversely, p[3] accesses the fourth element of the reallocated array, whose value is undefined as it was copied from data beyond the end of the original array passed to push().

Here is a modified version:

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

int *push(int *arr, size_t count, int val) { 
    int *arr2 = calloc(count   1, sizeof(int));
    for (int i = 0; i < count; i  ) {
        arr2[i] = arr[i];
    }
    arr2[count] = val;
    return arr2;
}

int main(int argc, char *argv[]) {
    int myNums[] = { 1, 2, 3 };
    int *p = push(myNums, sizeof(myNums) / sizeof(myNums[0]), 4);
    printf("%i\n", *(p   3));
    printf("%i\n", p[3]);
    free(p);
    return 0;
}
  •  Tags:  
  • c
  • Related