【问题标题】:Not sure how to use malloc() and free() properly不确定如何正确使用 malloc() 和 free()
【发布时间】:2015-07-20 11:55:30
【问题描述】:
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()

【问题讨论】:

  • 你不能释放内存然后使用它。您可以将它存储在一个临时变量中,免费使用,然后返回它。 int t = *len; free(len); return t;
  • 1)。你没有用 0 初始化 len。2)你访问了 free'ed 内存。
  • 在这个函数中没有任何理由动态分配根本。只需声明一个本地int len = 0; 累积您的计数,然后return len;
  • free(len) 之前,您需要将len 指向的值存储在其他变量中。例如:int len2 = *len。这基本上消除了len 动态分配的全部要点,您也可以静态分配它(即int len)。通常,当所需的内存量仅在运行时已知时,您需要使用动态内存分配。在给定的示例中,所需的内存量 - sizeof(int) - 在运行时之前是众所周知的(恒定且固定)。
  • 另外,您应该在访问内存之前检查 malloc 返回的值。 'if (!len) return -1;'

标签: c pointers memory-management malloc free


【解决方案1】:

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

   free(len);
   return *len;

是错误且未定义的行为。

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

还有,FWIW,

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

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

此外,在使用返回的指针之前,您应该始终检查 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; 
}

【讨论】:

  • 您只解决了编码错误,而不是标题中给出的(更一般的)问题 - 何时致电 malloc。您可能要提到,当所需的确切内存量在运行时已知时,需要动态内存分配,而静态内存分配通常应在所有其他情况下使用。
  • @barakmanos 我认为标题具有误导性,请参阅问题正文的最后一行。 :-)
  • @barakmanos OP 想了解指针。但是,关于您真正有用的评论,我已经更新了我的答案。请查阅。 :-)
  • 完成,+1.......顺便说一句,在最后一个代码示例中,确实不需要 if 语句(没有它会返回 0)。
【解决方案2】:

一般来说:在你拥有free()'d 一个内存块之后,你必须永远再访问它。想想已经放弃了那个街区。它不再是你的了!

由此可知,只有当您不想再访问某个​​块时,您才需要释放它。这是一个基本规则;永远不要破坏它。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-29
    • 2012-01-05
    • 1970-01-01
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 2020-08-26
    相关资源
    最近更新 更多