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()
?
答案 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节。