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 top[0]
happens to have the value1
. 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 topush()
.
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;
}