释放需要返回但不能在c中的main中释放的动态分配的int

Freeing dynamically allocated int that needs to be returned but cannot be freed in main in c

正如我的长标题所说:我正在尝试 return 动态分配的 c 中的指针,我知道,我必须释放它,但我不知道如何对自己进行搜索已经表明它只能在 main 中释放,但我不能让用户释放 int。

我的代码现在看起来像这样,

int *toInt(BigInt *p)
{
    int *integer = NULL;

    integer = calloc(1, sizeof(int));

    // do some stuff here to make integer become an int from a passed
    // struct array of integers

    return integer;
}

我试过只创建一个临时变量并查看整数,然后释放整数并 returning 临时变量,但这没有用。必须有一种方法可以在不释放 main 的情况下做到这一点?

别再把它当成指针了,没必要单独的int.

Return直接使用,不会有内存管理问题,因为是自动分配的:

int toInt(const BigInt *p)
{
  int x;
  x = do some stuff;
  return x;
}

来电者只需做

const int my_x = toInt(myBigInt);

my_x超出范围时会自动清除。

程序设计方面,您应该始终让进行分配的 "module"(翻译单元)负责释放内存。期望其他模块或调用者调用 free() 内存确实是糟糕的设计。

不幸的是 C 没有 constructors/destructors(也没有 "RAII"),所以这必须通过单独的函数调用来处理。从概念上讲,您应该像这样设计程序:

#include "my_type.h"

int main()
{
  my_type* mt = my_type_alloc();
  ...
  my_type_free(mt);
}

根据你的具体情况,不需要动态分配。只需将分配留给调用者,并使用专用的错误类型来报告错误:

err_t toInt (const BigInt* p, int* integer)
{
   if(bad_things())
     return ERROR;

   *integer = p->stuff();

   return OK;
}

其中 err_t 是一些自定义错误处理类型(可能是枚举)。

正如@unwind 已经观察到的,您的特定代码没有从动态分配中获得任何有用的信息。只要避免它,你就可以为自己省去很多麻烦。

从更一般的意义上讲,您应该想象每个分配的内存块都与隐含的释放义务相关联。该义务没有物理或电子表示,但您可以将其想象为在分配的生命周期内在任何给定时间最多与指向 space 的指针的一个副本相关联的虚拟支票。您可以随意在指针值的副本之间转移义务。如果带有义务的指针值因超出范围或被修改而丢失,那么您就有泄漏,至少在原则上是这样;如果您通过当时不承担释放义务的指针副本释放 space,那么您将获得(可能是虚拟的)双重释放。

I know I have to free it, but I do not know how to myself

分配内存的函数和 returns 指向它的指针副本而不创建任何其他副本(例如您的示例)应该假定将释放义务与返回的指针值相关联。它不能释放分配的 space 本身,因为 space 必须在函数 returns 之后保持分配(否则返回的指针比无用更糟糕)。如果释放的义务没有转移到返回的指针,那么当函数的局部变量在其末尾超出范围时,将发生(虚拟)内存泄漏,没有留下具有释放义务的指针的现存副本。

I cannot leave it up to the user to free the int.

如果你的意思是你不能把它留给来电者,那你就错了。当然,您 可以 将其留给调用者。如果实际上该函数按照您的描述分配了 space 和 returns 指向它的指针,那么它 必须 将释放的义务与返回的一起转移给调用者指向已分配 space 的指针的副本。这正是 calloc() 函数最初所做的。其他函数也是类似的,比如POSIX的strdup().

因为没有免费义务的物理或电子表示,所以您的功能 文档 任何此类义务对调用者来说至关重要。