0

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?

Rüppell's Vulture
  • 3,583
  • 7
  • 35
  • 49
linusz
  • 743
  • 1
  • 14
  • 26

4 Answers4

3

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];
Rohan
  • 52,392
  • 12
  • 90
  • 87
  • @Rüppell'sVulture, not sure what are you asking. – Rohan May 15 '13 at 08:00
  • Nothing,there was a misunderstanding about the `.....` part.I thought you had supplanted the `malloc()` segment to outside the loop.But it works fine when we use `int **a = malloc(sizeof(int *) * 4);` and leave the rest of the program intact.Maybe that's what you meant and I misread it. – Rüppell's Vulture May 15 '13 at 08:02
1

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]));
}
0

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.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
0

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.

user2384250
  • 548
  • 5
  • 13