【问题标题】:C functions requiring explicit call to free()需要显式调用 free() 的 C 函数
【发布时间】:2017-10-07 18:21:21
【问题描述】:

我想知道所有在内部使用 malloc() 并返回指向新分配的内存块的指针的 C 标准函数。 AFAIK 有:

  • strdup()
  • getcwd()
  • get_current_dir_name()

是这样吗?我正在编写一个复杂的解析器,它将所有 C 原始指针更改为更精细的 C++ 智能指针,我需要知道哪些地方不能自动完成。

【问题讨论】:

  • getcwd 被指定(在 POSIX 规范中)分配内存。见this official getcwd reference
  • 你为什么要问?为什么你想要一些与堆分配相关的详尽函数列表?
  • 因为我正在编写一个复杂的解析器,它将所有 C 原始指针更改为更精细的 C++ 智能指针,我需要知道哪些地方不能自动完成。
  • 这个原因应该进入你的问题。不,您将无法可靠地自动化它。一些未来的研究项目将试图解决这个问题。如果您希望我提供更多信息,请通过电子邮件与我联系(提及该问题的 URL)并详细说明您的目标。
  • 一个难以自动化的 API 的一个很好的例子是 Posix 版本的 scanf,它允许字符串转换通过分配分配字符 m 进行选择性修改,这将自动分配一个缓冲区大小正确,将其地址存储在相应的参数中,该参数必须是char** 而不是char*。由于格式字符串是一个函数参数,不一定是字符串文字,因此在某些情况下正确检测将是推测性的。

标签: c memory-management malloc free


【解决方案1】:

名单是:

  • malloc
  • calloc
  • realloc
  • aligned_alloc(C11 中的新功能)

您列出的函数都不是标准 C。

【讨论】:

  • 对不起,我的意思是:在内部使用 malloc() 并返回指向新分配的内存块的指针的函数列表。
  • @PhilBouchard 这不会改变答案。
  • 你好像忘了aligned_alloc
  • @rici 不是真的忘记,更像是从未听说过。 :-)
【解决方案2】:

您的列表相当正确,但 strdupgetcwd 是 POSIX(在 C99 中未标准化),而 get_current_dir_name 是 GNU(甚至不是 POSIX)。

您会发现其他函数返回一些堆分配的数据。

但您始终应该在使用某些功能之前阅读它的文档。它会告诉你返回的值是否是堆分配的(以及应该由谁以及如何释放)。

某些函数采用指针地址并可能更改它。例如getline(3) (POSIX) 或asprintf(3)open_memstream(3)(某些分配甚至可能在稍后发生)。

顺便说一句,像fopen 这样的一些标准函数可能正在使用堆分配的内存(在fclose 时间被释放)。

同样,对于您自己的库,请充分记录它们以明确说明谁负责free-in g(或以其他方式销毁)每个堆分配的指针。即使是您自己的私有函数,也要在 cmets 中记录。

自动检测与动态堆内存分配相关的函数很困难,并且在一般情况下可能无法可靠地完成(请参阅Rice's theorem),因此这是一个有趣的研究项目。

【讨论】:

  • getcwd分配内存。
【解决方案3】:
  1. void* malloc (size_t size);

分配一块大小字节的内存,返回一个指向块开头的指针。

  1. void* realloc (void* ptr, size_t size);

改变ptr指向的内存块的大小。

  1. void* calloc (size_t num, size_t size);

为由 num 个元素组成的数组分配一块内存,每个元素的大小为字节长,并将其所有位初始化为零。

【讨论】:

    猜你喜欢
    • 2015-03-21
    • 2023-04-07
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 2016-08-02
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多