1

I've just started programming in C a month ago and I apparently don't understand something about memory allocation even though I've read about it from few different sources.

If somebody could explain why this easy example I made crashes, I would be very grateful. (sorry for bad english)

void test(double *x)
{
    x = (double *)malloc(2 * sizeof(double));
    x[0] = 2;
    x[1] = 3;
}

int main()
{
    double *x = NULL;
    test(x);

    printf(" %f", x[0]); //this is where it crashes with no message 
}
Ihor Dobrovolskyi
  • 1,241
  • 9
  • 19
  • 4
    Please remove the `c++` tag. *We are at war with `c`*. <- Joke. Lighten up. But seriously, you should remove the `c++` tag. Those are two different languages these days. –  Dec 26 '16 at 20:06
  • A debugger, and two breakpoints. one at the end of `test`, and one on the `printf` in `main`, will demonstrate the problem if you examine the address stored in `x` in both cases. Hint: the assignment `x = ...` in `test` means *nothing* to the caller (`main`), and `x` there remains unchanged. – WhozCraig Dec 26 '16 at 20:08
  • 1) do not cast the returned value from `malloc()` 2) to change a pointer in the calling program to point to a new address, the pointer has to be passed as a `pointer to a pointer`. I.E. `test( &x);` and the function test needs to have the signature: `void test(double **x)` Notice the `**`. Then setting the value must dereference that passed pointer. I.E. `*x = malloc(2 * sizeof(double));` then since the 'x' is a pointer to a pointer (and paying attention to C operator precedence) use : `(*x)[0] = 2;` – user3629249 Dec 27 '16 at 05:49

2 Answers2

3

Your problem isn't with memory allocation. It is with C's passing of parameters by value. Your function allocates the memory but can't update the passed in parameter because it only has its value, not its address.

Try

void test(double **x)
{
    *x = (double *)malloc(2*sizeof(double));
    (*x)[0] = 2;
    (*x)[1] = 3;
}
int main()
{
    double *x = NULL;
    test(&x);

    printf(" %f", x[0]); //this is where it crashes with no message 
}
DrC
  • 7,528
  • 1
  • 22
  • 37
-1

I don't know exactly as to why the pointer does not update but if you was to pass in a struct with a pointer it would work other wise you need to update the pointer like so. Also you only need to cast data type if the pointer you are assigning to is type void.

double *test()
    {
        double *x = malloc(2*sizeof(double));
        x[0] = 2;
        x[1] = 3;
        return x;
    }

int main()
{
    double *x = test();


    printf(" %f", x[0]); //this is where it crashes with no message 
}
  • Function argument, passed and received? – Weather Vane Dec 26 '16 at 20:13
  • It's the only way to do it otherwise you need to pass in a pointer to the pointer, whatever your preference. – Black White Dec 26 '16 at 20:19
  • Oh thanks xD i just noticed i forgot to set the function argument! – Black White Dec 26 '16 at 20:20
  • 1
    What I am saying, is that you do not declare a function arguemnt, but you pass one that is not used. – Weather Vane Dec 26 '16 at 20:20
  • Returning the allocated pointer is one of two ways to resolve the problem (the other is to pass a pointer to the pointer). If you return the allocated pointer, you don't need to pass in a pointer — all you do is overwrite the passed in value with the value returned by `malloc()`, which makes passing the argument pointless. That means your function should be: `double *test(void) { double *x = malloc(2 * sizeof(double)); x[0] = 2.0; x[1] = 3.0; return x; }` — with consequential changes in the call (no argument; just as well since `x` isn't initialized when you pass it). – Jonathan Leffler Dec 26 '16 at 20:41
  • Your right I did not read my code properly x = func() is enough – Black White Dec 26 '16 at 20:45
  • Although double *x = func(x); would still work so i don't understand the downvote – Black White Dec 26 '16 at 20:49