不确定如何正确使用 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 节。