0

I'm trying to understand why this doesn't work as I want it to. I'm trying to malloc an integer pointer inside a function and return to the main function with the values intact. I assumed you can do this as the integer pointer is just an address, same with the size variable. So I thought the newPtr will have the contents of the values but it does not. Why is this?

I tried to see how to make this work but only idea I've come up with is to make function parameter type int * * arr.

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

bool readData(int * arr, int * size);


int main() {
    int i;
    int countSize = 10;
    int * newPtr;

    bool rtv = true;
    rtv = readData(newPtr, &countSize);
    if (rtv == false) {
        printf("read data failed\n");
        return -1;
    }

    for (i = 0; i < countSize/2; i++) {
        printf("%d\t", newPtr[i]);
    }
    printf("\n");
    printf("new size: %d\n", countSize);
    free(newPtr);

    return 0;
}

bool readData(int * arr, int * size) {
    int i;

    arr = malloc(sizeof(int*) * *size);
    if (arr == NULL) {
        printf("malloc error\n");
        return false;
    }

    for (i = 0; i < *size; i++) {
        arr[i] = i * i;
    }

    for (i = 0; i < *size; i++) {
        printf("[%d] = %d\n", i, (arr)[i]);
    }
    *size = *size * 2;
    return true;
}
Saxtheowl
  • 4,136
  • 5
  • 23
  • 32
Turbo012
  • 1
  • 2
  • It's far from clear why you'd manipulate `size` when that value is never used once modified. Sending it in as a pointer just over-complicates things. You iterate over half the array, because only half the array "exists", making that size misleading. – tadman Oct 04 '19 at 03:43
  • Sorry this was just an example to see why int * arr didn't work. int * size is there as a placeholder as I am using in my program. – Turbo012 Oct 04 '19 at 08:26

1 Answers1

0

The trouble is you're using a regular pointer:

bool readData(int * arr, int * size)

So when you assign in there like this:

    arr = malloc(sizeof(int*) * *size);

You're changing the local value of the pointer. To manipulate the root value, you need to do this:

bool readData(int** arr, int * size)

Where then you do:

    *arr = malloc(sizeof(int*) * *size);

That's kind of messy though. Instead just shift that to a return value:

int* readData(int * size) {
   int* arr = malloc(...);

   // ...
   return arr;
}

And capture that at the top:

int* rtv = readData(&countSize);

Where you can always return NULL if something went horribly wrong.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • Thank you for your help. I guess the best way to understand it is to think of it as a local variable. I used your first method as I needed to return a boolean value. It's just weird to see int ** arr as this reminds me of a 2 dimensional array. – Turbo012 Oct 04 '19 at 04:26
  • 1
    Arrays are not pointers and pointers are not arrays (though an array will decay to a pointer on access) `int**` is a single *pointer-to-pointer* to `int`. You first allocate for some number of pointers and assign that block to your pointer (e.g. `int **data = malloc (nptrs * sizeof *data);`) and then you allocate however many `int` that will be accessed through each pointer (e.g. `data[i] = malloc (numint * sizeof *data[i]);` Remember ***validate*** every allocation. – David C. Rankin Oct 04 '19 at 05:18