【问题标题】:How does one use C pointer wrapper functions idiomatically?如何习惯性地使用 C 指针包装函数?
【发布时间】:2017-05-03 08:37:11
【问题描述】:

21 世纪 C

避免与 malloc 相关的错误的最简单方法是不使用 malloc。

生产代码往往很少使用 malloc,通常包装在 new/copy/free 函数中,因此主代码不必进一步处理内存管理。

主要问题:有人可以提供一个超级简单、惯用的示例,说明如何使用这样的函数包装器来颠覆freemalloc 的直接用法?

次要问题(可选): 特别是,巧妙地使用此类函数能否模拟 C++ shared_ptrunique_ptr 的行为(甚至某些行为)?也就是说,使用这些函数可以让您不必担心您可能会意外释放悬空指针和/或创建泄漏?或者这在 C 语言中是不可能的,即使使用这样的函数?

【问题讨论】:

  • 关于第二个问题,C++ 智能指针过于依赖 RAII,这只是因为当局部变量超出范围时会自动调用析构函数。可以使用宏来模拟其中的一些功能,但远不如 C++ 中的可靠。
  • 你不能通过包装malloc来封装内存管理。我不知道那本书的作者在抽什么烟。
  • @n.m.我想他/她正在谈论添加编译时类型检查。
  • 谁能提供一个超级简单、惯用的例子……”你读的这本书没有提供一些东西吗?
  • "或者这在 C 语言中是不可能的" 是的,至少如果你不关心你在做什么的话。 C 是“危险的”,因为您通常在 自己动手 时会这样做。 “...即使使用这些功能?”是的,再次。

标签: c pointers


【解决方案1】:

这里有两个流行的成语:

‌1. malloc 的包装器,使其“永不失败”:

void safe_malloc(size_t size)
{
    char *ret = malloc(size);
    if(ret == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    return ret;
}

这样,您可以随时随地调用safe_malloc,而不必担心检查其返回值。但是您只能在不介意 malloc 失败时程序会自发退出的程序中使用此习惯用法(即,如果在这种情况下无需担心数据丢失)。

‌2。特定结构类型的“新”函数:

struct whatever *new_whatever()
{
    struct whatever *ret = safe_malloc(sizeof(*ret));
    initialize_whatever(ret);
    return ret;
}

我不确定这些是你要找的东西,我也不确定它们是 Ben Klemens 所说的。这些并不能真正“解决”内存分配问题——它仍然很麻烦——但它们有所帮助。

【讨论】:

    【解决方案2】:

    这样的? (它会添加一些类型的编译时检查,但仅此而已)

    typedef struct a_ {
       int a;
       int b;
    } a;
    
    a *new_a() {
         return malloc(sizeof(a));
    }
    
    void free_a(a *p) {
         free(p);
    }
    

    第二个问题:Smart pointers/safe memory management for C?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 2021-11-02
      相关资源
      最近更新 更多