不确定如何正确使用 malloc() 和 free()
Not sure how to use malloc() and free() properly
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()
?
内存一旦free()
就不能再使用了。所以,
free(len);
return *len;
是错误的未定义行为。
相反,您可以使用局部变量来保存 值 和 return
它。
此外,FWIW,
int *len = (int *)malloc(sizeof(int));
if(!r) {
free(len);
return *len;
}
在上面的代码中,您试图将 *len
用作 return 值,该值是 未初始化的 。即使没有 free()
ing,你也不应该那样做。
此外,在使用 returned 指针之前,您应该始终检查 malloc()
是否成功。
修改版本:
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;
}
一般来说:在你拥有 free()
一个内存块之后,你必须 永远不会 访问它。想想已经放弃了那个街区。它不再是你的了!
由此可见,只有当您不想再访问某个块时,您才必须释放它。这是一个 基本 规则;永远不要打破它。
对于这个例子,正如其他人所说,实际上根本不需要使用动态内存。
哦,还有:你真的不应该转换 malloc 的结果!它 returns void *
可以分配给任何其他指针类型。阅读 standard,第 6.5.16.1 节。
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()
?
内存一旦free()
就不能再使用了。所以,
free(len);
return *len;
是错误的未定义行为。
相反,您可以使用局部变量来保存 值 和 return
它。
此外,FWIW,
int *len = (int *)malloc(sizeof(int));
if(!r) {
free(len);
return *len;
}
在上面的代码中,您试图将 *len
用作 return 值,该值是 未初始化的 。即使没有 free()
ing,你也不应该那样做。
此外,在使用 returned 指针之前,您应该始终检查 malloc()
是否成功。
修改版本:
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;
}
一般来说:在你拥有 free()
一个内存块之后,你必须 永远不会 访问它。想想已经放弃了那个街区。它不再是你的了!
由此可见,只有当您不想再访问某个块时,您才必须释放它。这是一个 基本 规则;永远不要打破它。
对于这个例子,正如其他人所说,实际上根本不需要使用动态内存。
哦,还有:你真的不应该转换 malloc 的结果!它 returns void *
可以分配给任何其他指针类型。阅读 standard,第 6.5.16.1 节。