0

I don't understand why when I run this code, the printf statements aren't working. Here is the code:

typedef struct list {
    int n;
    struct list *next;
}List;

List **head;


List *tmp=malloc(sizeof(List));
tmp->n=34;
tmp->next=NULL;
List *tmp2=malloc(sizeof(List));
tmp2->n=45;
tmp2->next=NULL;
List *tmp3=malloc(sizeof(List));
tmp3->n=26;
tmp3->next=NULL;


head=malloc(sizeof(head));
head[0]=tmp;
head[1]=tmp2;
head=realloc(head,sizeof(head));
head[2]=tmp3;
printf("n of tmp:%d \n",head[0][0].n);
printf("n of tmp2:%d \n",head[1][0].n);
printf("n of tmp3:%d \n",head[2][0].n);

I think that the reason for that is probably realloc, but why ? I'm using it properly, no ? I have followed this tutorial http://www.tutorialspoint.com/c_standard_library/c_function_realloc.htm

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Luca
  • 55
  • 7

2 Answers2

2

Not only realloc, here

head = malloc(sizeof(head));

You allocate space for just one pointer, and then

head[0]=tmp;
head[1]=tmp2;

you try to store 2.

If you need space for 2 pointers, then the correct way is

head = malloc(2 * sizeof(*head));
    /*                   ^ always dereference when using sizeof */
    /* in this case it's not a problem, but in other cases it will be */

then you can fill the two elements, after checking the return value of malloc() so

head = malloc(2 * sizeof(*head));
if (head == NULL)
    doSomething_But_DontDereference_head_mayBe_exit();
head[0] = tmp;
head[0] = tmp2;

Now, realloc(), what if realloc() returns NULL, and you alread overwrite the head pointer, now you can't do anything else with it, so

void *pointer;

pointer = realloc(head, 3 * sizeof(*head));
if (pointer == NULL)
    doSomethingAndProbablyFree_head_and_abort();
head = pointer;

is much safer.

And also, note that you need to multiply the size of the pointer sizeof(*head) by the number of pointers you want to store.

ALWAYS CHECK THE RESULT OF malloc()

David Ranieri
  • 39,972
  • 7
  • 52
  • 94
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
-1

Your code is relatively broken. Here's a fairly sane way of going about this:

typedef struct list {
    int n;
    struct list *next;
} List;

int main() {
    List *tmp1 = malloc(sizeof(List));
    tmp1->n = 34;
    tmp1->next = NULL;

    List *tmp2 = malloc(sizeof(List));
    tmp2->n = 45;
    tmp2->next = NULL;

    List *tmp3 = malloc(sizeof(List));
    tmp3->n = 26;
    tmp3->next = NULL;

    List **head = malloc(2 * sizeof(List *));
    head[0] = tmp1;
    head[1] = tmp2;
    head = realloc(head, 3 * sizeof(List *));
    head[2] = tmp3;

    printf("n of tmp1: %d\n", head[0]->n);
    printf("n of tmp2: %d\n", head[1]->n);
    printf("n of tmp3: %d\n", head[2]->n);
}

I haven't included this, but you should also verify that malloc() and realloc() return a non-null pointer.

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173