0

I am absolutely new to C and I tried to initialize a array in a function.

But it doesn't work, because if I want to print the values in the main method I always get a Segmentation fault.

 static void array(int *i)
{
    int j = 0;
    i = (int *) malloc(5 * sizeof (int));
    for (j = 0; j < 5; j++) {
        i[j] = j;
    }

    for (j = 0; j < 5; j++) {
        printf("Hello: %d\n", i[j]);
    }
}

/* Main entry point */
int main(int argc, char *argv[])
{
    int j;
    int *i = NULL;

    array(i);
    for (j = 0; j < 5; j++) {
        printf("Hello: %d\n", i[j]);
    }
    return 0;
}

Would be nice if someone could fix the code and could explain how it works.

m.s.
  • 16,063
  • 7
  • 53
  • 88
MeJ
  • 1,088
  • 10
  • 18
  • 3
    `i = (int *) malloc(5 * sizeof (int));` only affects the copy of the pointer the function got, not the pointer in the caller. Let me find a duplicate. – Daniel Fischer Oct 22 '12 at 19:12
  • In other words: the pointer is passed as value, not as reference, and thus doesn't get updated. The value for i got its original value when you exit array() function. – m0skit0 Oct 22 '12 at 19:14
  • Don't cast the result of `malloc`. – chris Oct 22 '12 at 19:23
  • But I think we have to cast the result of malloc the be compatible with c++. – MeJ Oct 22 '12 at 19:43

2 Answers2

3
static void array(int **i)
{
    int j = 0;
    *i = malloc(5 * sizeof (int));
    for (j = 0; j < 5; j++) {
        (*i)[j] = j;
    }

    for (j = 0; j < 5; j++) {
        printf("Hello: %d\n", (*i)[j]);
    }
}

/* Main entry point */
int main(int argc, char *argv[])
{
    int j;
    int *i = NULL;

    array(&i);
    for (j = 0; j < 5; j++) {
        printf("Hello: %d\n", i[j]);
    }
    return 0;
}

You are passing a pointer by value into array, so what you need to do is pass a pointer to your pointer instead, then set/use that.


As for why you shouldn't cast the result of a malloc, see: Do I cast the result of malloc? and Specifically, what's dangerous about casting the result of malloc?

Community
  • 1
  • 1
hexist
  • 5,151
  • 26
  • 33
  • Lets say that we want to copy a other array int this one: how would i work: memcpy(*i, j, 5* sizeof (int)); Why do I have to use *i and not &i in this function? – MeJ Oct 22 '12 at 19:28
  • in `array` `i` is a pointer to your `i` in main, so to refer to that `i` in main, you have to use `*i`. – hexist Oct 22 '12 at 19:41
  • As for your `memcpy` question, lookup `memcpy`, it expects two pointers and a size to copy, just make sure you pass it the `i` in your main (either by dereferencing `i` in `array` or doing the `memcpy` in `main`.). You also need your second argument to be a pointer as well, so using `j` doesn't make sense since `j` is an integer. – hexist Oct 22 '12 at 19:42
  • 1
    Remove the superfluous, dangerous cast of malloc's return value and I'll upvote this. I know it is there in the OP's code, but we shouldn't teach anyone to do that. – Lundin Oct 22 '12 at 19:49
  • Done, with a note about why casting malloc is bad – hexist Oct 22 '12 at 20:08
1

In order to allocate memory to a variable from within a function, you must pass a pointer to a pointer as the function argument, dereference the pointer and then allocate the memory.

or in pseudo-code

function(int **i)
{
    *i = malloc...
}
int *i = NULL;
function(&i);

This is one of the ways to do it. You could also return the pointer which malloc returns. And, from the material I've read, it's a good practice to NOT cast the return type of malloc.

farmdve
  • 786
  • 3
  • 13
  • 26