linusz
linusz

Reputation: 783

Why am I getting segmentation fault for malloc() while using pointer to pointer?

I don't understand why this works:

void main() { 
    int *  b;
    b = (int *)malloc(sizeof(int));
    *b = 1;
    printf("*b = %d\n", *b);
}

while this does not (gets segmentation fault for the malloc()):

void main() {

    int ** a;
    int    i;

    for (i = 0; i<= 3; i++) {
        a[i] = (int*)malloc(sizeof(int));
        *(a[i]) = i;
        printf("*a[%d] = %d\n", i, *(a[i]));
    }
}

since I find a[i] is just like b in the first example.

BTW, a[i] is equal to *(a+i), right?

Upvotes: 0

Views: 127

Answers (4)

David Herviou
David Herviou

Reputation: 21

a is a 2 dimensional pointer, you have to allocate both dimension. b is a 1 dimensional pointer, you have to allocate only one dimension and that's what you're doing with

b = (int *)malloc(sizeof(int));

So in order the second example to work you have to allocate the space for the pointer of pointer

void main() {

int ** a;
int    i;
a = (int**)malloc(4*sizeof(int*));

for (i = 0; i<= 3; i++) {
    a[i] = (int*)malloc(sizeof(int));
    *(a[i]) = i;
    printf("*a[%d] = %d\n", i, *(a[i]));
}

Upvotes: 1

user2384250
user2384250

Reputation: 558

actually malloc it's not that trivial if you really want safe and portable, on linux for example malloc could return a positive response for a given request even if the actual memory it's not even really reserved for your program or the memory it's not writable.

For what I know both of your examples can potentially return a seg-fault or simply crash.

@ruppells-vulture I would argue that malloc is really portable and "safe" for this reasons.

Upvotes: 0

Rohan
Rohan

Reputation: 53326

You need to allocate memory for a first, so that you can access its members as a[i].

So if you want to allocate for 4 int * do

a = malloc(sizeof(int *) * 4);

for (i = 0; i<= 3; i++) {
  ...
}

or define it as array of integer pointers as

int *a[4];

Upvotes: 3

unwind
unwind

Reputation: 399793

The allocated pointer is written to uninitialized memory (you never set a to anything), causing undefined behavior.

So no, it's not at all equivalent to the code in the first example.

You would need something like:

int **a;

a = malloc(3 * sizeof *a);

first, to make sure a holds something valid, then you can use indexing and assign to a[0].

Further, this:

a[i] = (int*)malloc(sizeof(int));

doesn't make any sense. It's assigning to a[i], an object of type int *, but allocating space for sizeof (int).

Finally, don't cast the return value of malloc() in C.

Upvotes: 0

Related Questions