代码之家  ›  专栏  ›  技术社区  ›  Luca

使用指针对指针重新分配行为

  •  0
  • Luca  · 技术社区  · 11 年前

    我不明白为什么当我运行这段代码时 printf 声明不起作用。 代码如下:

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

    我认为这可能是因为 realloc ,但为什么?我用得很好,不是吗?我已经遵循了本教程 http://www.tutorialspoint.com/c_standard_library/c_function_realloc.htm

    2 回复  |  直到 11 年前
        1
  •  2
  •   David Ranieri    11 年前

    不仅如此 realloc 在这里

    head = malloc(sizeof(head));
    

    只为一个指针分配空间,然后

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

    您尝试存储2。

    如果需要2个指针的空间,那么正确的方法是

    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 */
    

    然后,在检查 malloc() 所以

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

    现在 realloc() ,如果 realloc() 回报 NULL ,并且您已覆盖 head 指针,现在你不能用它做任何其他事情,所以

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

    更安全。

    此外,请注意,您需要将指针的大小乘以 sizeof(*head) 根据要存储的指针数。

    始终检查的结果 malloc()

        2
  •  -1
  •   Bill Lynch    11 年前

    你的代码相对来说是坏的。这是一个相当理智的做法:

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

    我没有包括这一点,但你也应该验证一下 malloc() realloc() 返回非空指针。

    推荐文章