-1

In pseudo-code, I'd like to replace:

ra             =  (double *)  realloc(ra,   Num*sizeof(*ra));
dec            =  (double *)  realloc(dec,  Num*sizeof(*dec));
zobs           =  (double *)  realloc(zobs, Num*sizeof(*zobs));
M_B            =  (double *)  realloc(M_B,  Num*sizeof(*M_B));

with

e.g. mem_allocate(&ra, &dec, &zobs, &M_B)

where

mem_allocate(arg1, arg2,..., arg4){

for argi in arg1 to arg4{
     argi = (double *)  realloc(argi, Num*sizeof(*argi))

}

}
Lundin
  • 195,001
  • 40
  • 254
  • 396
Mike
  • 13
  • 3
  • 3
    How does the function know `Num`? Is it a constant? Wouldn't it be better to pass it as a parameter instead? – Lundin Feb 08 '17 at 14:46
  • You cannot loop over ordinary arguments in C. You could write this as a varargs function, however. That could be more flexible than a function for a fixed number of arguments. – John Bollinger Feb 08 '17 at 14:47
  • 3
    If you *are* going to rewrite it as a function then add better error handling. Particularly in not losing the address of the old memory block when `realloc` returns a null pointer. – StoryTeller - Unslander Monica Feb 08 '17 at 14:49
  • 1
    Note also that reallocation can fail. You've described no error handling, and performing a group reallocation like that makes error handling trickier than otherwise it is. – John Bollinger Feb 08 '17 at 14:49
  • 1
    Better using `bool mem_allocate(double *var[], size_t N_vars)` – LPs Feb 08 '17 at 14:50
  • Besides the loop issue, what problems do you have in the functions implementation? – Some programmer dude Feb 08 '17 at 14:50
  • 3
    Variable argument functions are almost always the wrong solution to any problem... If the problem is X and you think Y is the solution, then Z is a variable argument list function. :) – Lundin Feb 08 '17 at 14:50
  • 1
    @LPs Indeed, except he needs to change the pointers themselves. I don't believe that `realloc` guarantees that the address remains the same after calling it. – Lundin Feb 08 '17 at 14:52
  • @Lundin Should work fine with an array of pointers, as then the function can easily do `var[x] = new_pointer;` Or do you want an array of pointer *to* pointers? So e.g. `*var[x] = new_pointer;`? The first alternative requires some more work by the caller, but the second alternative leads to three-star programming... :) – Some programmer dude Feb 08 '17 at 14:54
  • @LP the function needs also a `size_t *sizes` that gives the size of each of `var[]` (and `Num`). – Déjà vu Feb 08 '17 at 15:01
  • @Someprogrammerdude I don't think realloc gives any choice in the matter. I'll consider writing an answer. – Lundin Feb 08 '17 at 15:01
  • @Lundin happy to add Num as argument, obviously that's the easy bit! – Mike Feb 08 '17 at 15:08
  • @StoryTeller Maybe you could give some detail on the error handling. I have limited/no experience of that. Reversion to malloc rather than realloc is a possibility – Mike Feb 08 '17 at 15:09
  • It is impossible to write a function having this exact calling sequence doing what you want. You can write a varargs macro though. – n. m. could be an AI Feb 08 '17 at 15:09
  • @Mike - The gist of it is just not assigning directly to the pointer you are reallocating. Assign to a temporary first, then check for NULL and handle the error as you see fit. If you got back a valid address you can overwrite the original pointer. – StoryTeller - Unslander Monica Feb 08 '17 at 15:10
  • @Someprogrammerdude I considered an array of pointers. My limited knowledge meant that the array initialisation reverted to practically the same number of lines of code. I'm hoping for a succint few-liner! Interested to hear three-star options, providing you explain it ;) – Mike Feb 08 '17 at 15:11
  • 1
    The fact that you are trying to have 4 arrays with the same number of elements strongly suggests that you are solving a wrong problem though. Perhaps you need a single array of structs instead. – n. m. could be an AI Feb 08 '17 at 15:14
  • Consider reading [Do I cast the result of malloc?](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Deduplicator Feb 08 '17 at 15:38

1 Answers1

1

For the sake of completeness of my previous comment, an example is

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

bool mem_allocate (double *vars[], size_t N_vars, size_t newWidth)
{
    double *temp;

    printf("\n");

    for (size_t i=0; i<N_vars; i++)
    {
        temp = realloc(vars[i], newWidth*sizeof(*temp));

        if (temp != NULL)
        {
            printf ("temp: %p\n", (void *)temp);
            vars[i] = temp;
        }
        else
        {
            return false;
        }
    }

    printf("\n");

    return true;
}

int main (void)
{
    double *var1 = malloc(sizeof(*var1));
    double *var2 = malloc(sizeof(*var2));
    double *var3 = malloc(sizeof(*var3));
    double *var4 = malloc(sizeof(*var4));

    printf ("var1: %p\n", (void *)var1);
    printf ("var2: %p\n", (void *)var2);
    printf ("var3: %p\n", (void *)var3);
    printf ("var4: %p\n", (void *)var4);

    double *vars[4];

    vars[0] = var1;
    vars[1] = var2;
    vars[2] = var3;
    vars[3] = var4;

    if (mem_allocate (vars, sizeof(vars)/sizeof(vars[0]), 200) == true)
    {
        var1 = vars[0];
        var2 = vars[1];
        var3 = vars[2];
        var4 = vars[3];

        printf ("var1: %p\n", (void *)var1);
        printf ("var2: %p\n", (void *)var2);
        printf ("var3: %p\n", (void *)var3);
        printf ("var4: %p\n", (void *)var4);
    }

    return 0;
}

Changing varx inside function mem_allocate would imply 3 star implementation, that I really don't love.

Obviously all malloc return value must be checked.

LPs
  • 16,045
  • 8
  • 30
  • 61