简体   繁体   中英

Realloc behaviour using a pointer-to-pointer

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

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()

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM