c - 为内存管理牺牲意图表达

标签 c memory-management

我是 C 编程的新手,而且这种类型的事情不断出现。作为一个简单的例子,假设我有一个带有一些 char 指针的 struct http_header:

struct http_header {
    char* name;
    char* value;
};

我想填充一个 http_header,其中 value 是一个 int 的字符串表示形式。我“感觉”在语义上,我应该能够编写一个函数,它接受一个空的 header 指针、一个名称字符串和一个 int 并适本地填写 header 。

void fill_header(struct http_header *h, char* name, int value)
{
    h->name = name;
    char *value_str = malloc(100);
    sprintf(value_str, "%d", value);
    h->value = value_str;
}

int main(int argc, const char * argv[])
{
    struct http_header h;
    char *name = "Header Name";
    int val = 42;
    fill_header(&h, name, val);
    ...
    free(h.value);
}

在这里,调用代码完全符合我的意图,但在这种情况下,我正在动态创建 value 字符串,这意味着我必须稍后释放它。我觉得那味道不对;调用者似乎对 fill_header 的实现了解得太多了。在实际实现中,要知道要释放什么可能并不那么容易:考虑填充一个 http_header 数组,其中只有一个需要将其值 malloced。

为了解决这个问题,我必须事先创建字符串:

void fill_header2(struct http_header *h, char* name, char *value_str)
{
    h->name = name;
    h->value = value_str;
}

int main(int argc, const char * argv[])
{
    struct http_header h;
    char *name = "Header Name";
    int value = 42;

    char value_str[100];
    sprintf(value_str, "%d", value);
    fill_header2(&h, name, value_str);
}

随着这种模式沿着结构链向下延伸并指向其他结构,我最终在顶层函数中做了很多工作,而低层函数似乎不值得。此外,我基本上已经放弃了我最初打算编写的“用 int 填充 header ”的想法。我在这里错过了什么?是否有一些模式或设计选择可以让我的生活更轻松让我的函数调用表达我的意图?

附言感谢 Stackoverfow 的所有人,你们是我遇到过的最好的教授。

最佳答案

好吧,我会采用第一种方法(稍作改动),并提供一个destroy 函数:

struct http_header *make_header(char *name, int value)
{
    struct http_header *h = malloc(sizeof *h);
    /* ... */
    return h;
}

void destroy_header(struct http_header *h)
{
    free(h->name);
    free(h);
}

这样调用者就不必知道任何关于http_header的信息。

您也可以摆脱将主要分配(结构本身)留给调用者并自己进行内部分配的版本。然后,您必须提供一个 clear_header,它只会释放分配的 fill。但是这个 clear_header 给你留下了一个部分有效的对象。

关于c - 为内存管理牺牲意图表达,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8018995/

相关文章:

c - 是否可以重用 CryptVerifySignature() 哈希对象?

c++ - 测量 CPU 频率缩放效果

c - 将 void 指针与 C 中的类型化指针进行比较(为了相等)是 UB 吗?

c# - 为什么 "decimal"数据类型不可 blittable?

c++ - 我的内存泄漏在哪里?

c - 如何从 C 中的指针获取数组的大小?

c - 赋值原因不明确会丢弃 volatile 限定符

c - 在结构中初始化数组的值

swift - 闭包比其创建的实例活得更久

javascript - 如何检测触发 JavaScript 垃圾回收的内存分配?