不确定如何正确使用malloc()和free()

时间:2015-05-09 17:21:36

标签: c pointers memory-management malloc free

int listLength(struct node *r) { 

    int *len = (int *)malloc(sizeof(int));
    if(!r) { 
       free(len);
       return *len; 
    }

    while(r) { 
         r = r->next; 
           *len += 1; 
    }
    free(len)
    return *len; 
}

我写了这个函数来计算链表的长度。我仍然通过与他们一起玩来学习指针。我知道我可以在函数中使用一个简单的len变量,但我想学习动态内存分配的基础知识。为什么即使列表中的元素很少,长度也始终为0?应该何时调用free()

2 个答案:

答案 0 :(得分:3)

free()后,您无法使用内存。所以,

   free(len);
   return *len;

是错误且未定义的行为。

相反,您可以使用局部变量来保存return

此外,FWIW,

int *len = (int *)malloc(sizeof(int));
    if(!r) { 
       free(len);
       return *len; 
    }

在上面的代码中,您尝试使用*len作为返回值,即未初始化。即使没有free(),你也不应该这样做。

此外,您应该始终使用返回的指针检查malloc() vefore是否成功。

修改后的版本:

int listLength(struct node *r) { 

    int *lenp = malloc(sizeof(int));
    int len = 0;

    if (!lenp)     //check malloc success
        exit(-1);    


    *lenp = len;

    if(!r) { 
       free(lenp);
       return len; 
    }

    while(r) { 
         r = r->next; 
           *lenp += 1; 
    }

    len = *lenp;
    free(lenp);
    return len; 
}

编辑:

在您的情况下,根本不需要使用动态内存分配。根据 @ Barak Manos 先生和 @ WhozCraig 先生的建议,只有在编译时不知道内存要求时才应使用动态内存分配。否则,一般情况下,静态(编译时)内存分配应该没问题。

更好,更清晰的代码方法,

int listLength(struct node *r) { 

    int len = 0;

    while(r) { 
         r = r->next; 
           len += 1; 
    }
    return len; 
}

答案 1 :(得分:0)

一般情况下:在您拥有free()个内存块之后,您必须永远不会访问它。想想已经把那个街区拿走了。它不再是你了!

从这一点开始,只有在您不想再访问它时才必须释放一个块。这是基本规则;从来没有打破它。

对于这个例子,正如其他人所说,实际上根本不需要使用动态内存。

哦,而且:你真的不应该施放malloc的结果!它返回void *,可以分配给任何其他指针类型。阅读standard,第6.5.16.1节。