c - 反对 free_if_heap(void *ptr)?

标签 c malloc

我经常想使用一个假设的 free_if_heap(void *ptr) 函数,因为这可以让我不关心地返回 malloc、静态或堆栈对象。例如

char *foo(int arg) {
    if (arg < 0) {
        return "arg is negative";
    }

    if (arg > 0) {
        size_t size = snprintf(NULL, 0, "%i is an invalid value", arg);
        char *ret = malloc(size + 1); // FIXME: handle failure
        sprintf(ret, "%i is an invalid value", arg);
        // I use a varargs macro for the three lines above, to avoid format string duplication errors.
    }

    return NULL;
}

void main(void) {
    for (int i = -1; i < 2; ++i) {
        char *err = foo(i);
        if (err) {
            printf("Error: %s\n", err);
            free_if_heap(err);
        }
    }
}

显然这样的函数一定不是一个好主意,因为它甚至从未达到过 malloc 库的要求,更不用说 C 标准了。

为什么free_if_heap(void *ptr)是一个坏主意?


更新:

函数 foo 只是一个函数示例,它可以返回指向 malloc 数据或静态/全局数据的指针。这不是一个有目的的严肃函数。


更新:

需要知道指针(已知类型的指针,例如 char *)是否指向堆与需要知道 void * 数据类型不同> 指针指向。

free_if_heap(void *ptr) 采用 void * 参数以避免出现 free_if_heap_char(char *ptr)free_if_heap_int( int *ptr) 和一百个其他变体。

最佳答案

函数void free_if_heap(void *ptr)无法可移植地实现*,但在选定的目标上可能是可能的,具体取决于malloc()的本地实现。

如果您不能或不想处理分配对象的生命周期,您应该使用不同的编程语言和垃圾收集器。 C 有许多有效的替代品,例如 Go。您还可以尝试使用 C 的保守垃圾收集器,例如 Boehm–Demers–Weiser garbage collector .

但请注意,跟踪内存分配的对象并在使用后正确处置它们并不那么困难,但需要一致的约定:例如,您的 foo 函数应始终返回分配的字符串或空指针:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *foo(int arg) {
    if (arg < 0) {
        return strdup("arg is negative");
    }

    if (arg > 0) {
        size_t size = snprintf(NULL, 0, "%i is an invalid value", arg);
        char *ret = malloc(size + 1);
        if (ret != NULL) {
            snprintf(ret, size + 1, "%i is an invalid value", arg);
            return ret;
        }
    }
    return NULL;
}

int main(void) {
    for (int i = -1; i < 2; ++i) {
        char *err = foo(i);
        if (err) {
            printf("Error: %s\n", err);
            free(err);
        }
    }
    return 0;
}

(*) 可移植的实现将是微不足道且无效的:void free_if_heap(void *ptr) {}

关于c - 反对 free_if_heap(void *ptr)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63408530/

相关文章:

c - 尝试将用户输入传递到我正在创建的简单 shell 中

c - C 中字符串函数 strlen() 的不同输出

C 释放动态分配的结构数组

c - 动态分配结构 vector 内存

c - 我收到错误 "warning: assignment to ' char' from 'char *' made integer frompointer without a Cast”

c - 如何更改 C 中结构属性的大小?

c - 如何检查我的程序返回的值?

python - Ctypes 找不到我加载的 dll 的 dll 依赖项

c - 在 C 中如何将 char 数组转换为 int 数组?

c - malloc 上已释放对象的校验和不正确