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;
}
