【问题标题】:is free()'ing dynamically allocated primitive arrays necessary in C?在 C 中是否需要 free()'ing 动态分配的原始数组?
【发布时间】:2014-01-30 22:33:34
【问题描述】:

例如,在计算树的高度时,请参见 int *heights = malloc(sizeof(int)...)。它是递归的,所以如果有内存泄漏,它会很大,有一棵大树。我知道一般规则是对每个 malloc 使用 free(),但这是否也适用于动态分配的原始类型?

typedef struct EQTNode {
    EQPos *pos;
    int genNumber;
    struct EQTNode * parent;
    int numberOfPossibleMoves;
    struct EQTNode ** children;
} EQTNode;

...

int EQTN_getHeight(EQTNode *node, int depth){
    if (node != NULL){
        int n = node->numberOfPossibleMoves;
        int *heights = malloc(sizeof(int) * n);
        for (int i = 0; i < n; i += 1){
            heights[i] = EQTN_getHeight(node->children[i], depth + 1);
        }
        int max = 0;
        for (int i = 0; i < n; i += 1){
            if (heights[i] > max){
                max = heights[i];
            }
        }
        return max;
    } else {
        return depth;
    }
}

【问题讨论】:

  • 是的,当然。为什么不呢?
  • malloc 不知道也不关心类型。如果你在某个时候分配了资源,你应该释放它。
  • 任何你使用 malloc 或 new 或 new[] 的东西,最终都必须分别使用 free 或 delete 或 delete[]。
  • “如果你使用正确的操作系统”——如果 OP 使用了正确的 算法,就不需要 malloc 或 free ...该数组毫无意义。
  • @R..是的,假装什么都不会出错是不好的......但这些都是有效的工具,应该明智地使用。

标签: c++ c arrays dynamic primitive


【解决方案1】:

除了你分配的东西的类型与你是否需要释放它无关之外,根本不需要 malloc/free:

if (node != NULL){
    int n = node->numberOfPossibleMoves;
    int max = 0;
    for (int i = 0; i < n; i++){
        int height = EQTN_getHeight(node->children[i], depth + 1);
        if (max < height)
            max = height;
    }
    return max;
}

【讨论】:

    【解决方案2】:

    以防万一 C99 启用可变长度数组,因此您的代码可以重写为:

       if (node != NULL){
            int n = node->numberOfPossibleMoves;
            int heights[n];
            for (int i = 0; i < n; i += 1){
                heights[i] = EQTN_getHeight(node->children[i], depth + 1);
            }
            int max = 0;
            for (int i = 0; i < n; i += 1){
                if (heights[i] > max){
                    max = heights[i];
                }
            }
            return max;
        } 
    

    在这种情况下,您不需要显式释放它。

    但是每个malloc() 调用都应该有对应的free() 对应物。

    【讨论】:

    • VLA 在这样的用例中几乎肯定会导致堆栈溢出(而不是好的那种)。
    • @R 是的。有很多方法可以用 C 枪击中自己的脚。这是其中之一。不打电话给free() 是另一种情况。虽然有些场景 VLA 和 alloca 非常有用。当然,在 TS VLA/alloca 所描述的递归情况下,看起来会很可疑。但是建议使用 malloc 看起来也很危险。只是那把枪比刻有VLA的枪更紧。
    • 完全不用 heights 数组写出来怎么样……没必要。
    【解决方案3】:

    您使用malloc 调用的任何内容都应由您明确指定为free()。 malloc() 只是为您分配一块内存,由您在使用完毕时告诉操作系统。

    查看malloc() 的手册页

    C 不是垃圾收集器,你知道 ;)

    【讨论】:

      【解决方案4】:

      是的。

      不然怎么释放内存?

      【讨论】:

        猜你喜欢
        • 2012-08-17
        • 1970-01-01
        • 2014-05-15
        • 2016-05-16
        • 2015-11-08
        • 1970-01-01
        • 2021-06-15
        • 2012-02-29
        • 1970-01-01
        相关资源
        最近更新 更多