-1

A C function can modify more than one variable by an illusion of pass-by-reference (a pass-by-value of address as explained by Ely), e.g.:

#include <stdio.h>

void function(int *pa, int *pb) {
    *pa *= *pa;
    *pb *= *pb;
}

int main(void) {
    int a = 1, b = 2;
    function(&a, &b);
    printf("a = %d\nb = %d\n", a, b);
    return 0;
}

which outputs

a = 1
b = 4

It is also possible to modify a whole range of variables by returning a pointer to an array, e.g.:

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

int *function(int *ptr_size) {
    int n = 6;  // arbitrary ptr_size
    int *array = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; ++i)
        array[i] = i * i;
    //
    *ptr_size = n;
    return array;
}

int main(void) {
    int size = 0;
    int *array = function(&size);
    printf("size = %d\n", size);
    for (int i = 0; i < size; ++i)
        printf("array[%d] = %d\n", i, array[i]);
    free(array);
    array = NULL;
    return 0;
}

which outputs :

size = 6
array[0] = 0
array[1] = 1
array[2] = 4
array[3] = 9
array[4] = 16
array[5] = 25

But what if I want a function that modify more than one (dynamic allocated) array ?
I tried this

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

void function(int *array, int *ptr_asize, int *brray, int *ptr_bsize) {
    int size = 6;
    array = (int *)malloc(size * sizeof(int));
    brray = (int *)malloc(size * sizeof(int));
    for (int i = 0; i < size; ++i) {
        array[i] = i * i;
        brray[i] = i * i * i;
    }
    *ptr_asize = size;
    *ptr_bsize = size;
}

int main(void) {
    int asize, bsize;
    int *array, *brray;
    function(array, &asize, brray, &bsize);
    // array
    printf("asize = %d\n", asize);
    for (int i = 0; i < asize; ++i)
        printf("array[%d] = %d\n", i, array[i]);
    free(array);
    array = NULL;
    // brray
    printf("bsize = %d\n", bsize);
    for (int i = 0; i < bsize; ++i)
        printf("brray[%d] = %d\n", i, brray[i]);
    free(brray);
    brray = NULL;
    //
    return 0;
}

but it makes a segmentation fault.
That is not very surprising, how main would know about how much memory has been allocated to array and brray?

So my question is: is it possible in C that a function allocate and modify more than one array, and those changes remain in main?

PS: A solution would be to allocate a new abrray that contains both array and brray (int **function(...) { ... return abrray; }), but I would like to know if it is possible to a function to modify two (or more) arrays, and that changes remain in main.

lavalade
  • 329
  • 2
  • 11
  • Not really! Actually, I do not even see the relation between both questions except they deal with pointers :-/. My question is _is it possible to allocate and modify two arrays within a function, and keep those changes in `main`?_, and if yes, how? – lavalade Aug 15 '20 at 07:24
  • It means you did not understand the answer. It tells you precisely how to return allocated memory from a function to the caller via a pointer. – kaylum Aug 15 '20 at 07:24
  • Exactly, that is why I ask this question! Futhermore, I did not found anywhere an exemple of function that allocate and modify two arrays... – lavalade Aug 15 '20 at 07:27
  • And that's what the linked post tells you. Ok, admittedly it shows you how to do it for one array. But that's the principle you need to know. It tells you how you can allocate memory in a function, set the pointer passed in by the caller and then the caller can use it. It shows you one array but any number of arrays can be done the same way just by passing in more function args. – kaylum Aug 15 '20 at 07:29
  • OK, it is clearer with this explanation. But I found those two questions quite far related for someone who begins with C, and I don’t think mine worth the downvoting (of course, anyone being downvoted would say the same), but thank you anyway, I know now how to do it and post MWE below. – lavalade Aug 15 '20 at 07:48
  • 1
    I didn't down vote you - I do agree that's a bit rough. Here, have an upvote :-) – kaylum Aug 15 '20 at 07:49
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219857/discussion-between-leaurendmalade-and-kaylum). – lavalade Aug 15 '20 at 07:50

2 Answers2

1

Pass a pointer to pointer, like this:

void func(int** array, int** brray, size_t size_a, size_t size_b) {
*array = malloc(size_a * sizeof(int));
*brray = malloc(size_b * sizeof(int));
}

Call it like:

int *arr, *brr;
func(&arr, &brr, 2, 5);
iTs.SL4y3R
  • 74
  • 8
0

As explained by iTs.SL4y3r, it is possible by passing pointer to pointer.
Here is a minimal working example :

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

void function(int **array, int *ptr_asize, int **brray, int *ptr_bsize) {
    int size = 6;
    *array = malloc(size * sizeof(int));
    *brray = malloc(size * sizeof(int));
    for (int i = 0; i < size; ++i) {
        (*array)[i] = i * i;
        (*brray)[i] = i * i * i;
    }
    *ptr_asize = size;
    *ptr_bsize = size;
}

int main() {
    int asize, bsize;
    int *array, *brray;
    function(&array, &asize, &brray, &bsize);
    // array
    printf("asize = %d\n", asize);
    for (int i = 0; i < asize; ++i)
        printf("array[%d] = %d\n", i, array[i]);
    free(array);
    array = NULL;
    // brray
    printf("bsize = %d\n", bsize);
    for (int i = 0; i < bsize; ++i)
        printf("brray[%d] = %d\n", i, brray[i]);
    free(brray);
    brray = NULL;
    //
    return 0;
}

which outputs :

asize = 6
array[0] = 0
array[1] = 1
array[2] = 4
array[3] = 9
array[4] = 16
array[5] = 25
bsize = 6
brray[0] = 0
brray[1] = 1
brray[2] = 8
brray[3] = 27
brray[4] = 64
brray[5] = 125
lavalade
  • 329
  • 2
  • 11