问题 如何释放函数返回的指针?


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

char* f(void) {
  char *x;
  x = malloc(sizeof(char) * 4);
  strcpy(x, "abc");
  return(x);
}

int main(void) {
  char *a;
  a = f();
  printf("%s", a);
  free(a);
  return(0);
}

是变量吗? x 在函数中必须被释放?如果是这样,当我需要退货时,这怎么可能呢?


12812
2017-08-09 22:32


起源

你为什么把parens放进去 return表达? - ouah
@ouah:风格问题。我不是个人,但我每天工作的项目都有。它也做了类似的事情 if(someBoolean == true) 我无法忍受,但我知道原来的程序员并不是不知道布尔类型(他是一个非常聪明的人),他只是喜欢它。 - Ed S.
每当你感觉到返回指向动态分配数据的指针的冲动时,你应该问自己:“为什么我要设计程序以便分配和释放在不同的代码模块中?”,“为什么代码不能理解使用同一模块中的数据的数据性质和代码?“以及与正确的OO设计相关的类似问题。 - Lundin


答案:


是否必须释放函数中的变量x?

是的(有点,见我后来的评论)。每次打电话 malloc 需要稍后的电话 free。否则,你有泄漏。但请记住;你不是“自由的” x“,你正在释放x所指的记忆。

你什么时候回来 x 一份副本  (地址) x 制作并返回给来电者。 x 声明具有自动存储持续时间。它所引用的内存必须被释放。

如果是这样,当我需要返回时,这怎么可能。

您的设计将责任放在呼叫者身上以释放内存。你已经完成了这个。当然,使用此方法需要您记录该函数,以便代码的用户知道他们正在接收动态分配的内存地址。

更好的方法(IMO)是将缓冲区作为输入参数。现在很清楚谁负责管理这个内存(即调用者)。也许我甚至不想动态分配它。有了这个设计,这是我的选择。

void f(char *buf, size_t buf_size) {
  strncpy(buf, "abc", buf_size - 1);
  buf[buf_size-1] = '\0';
}

另外,您应该始终检查返回值 malloc。它可能会失败,在这种情况下将返回空指针。也, sizeof(char) 保证是 1 按标准,所以你可以删除那一点,然后说 malloc(n)


9
2017-08-09 22:34





是的,应该由呼叫者释放。如那个 free 在你的主要。

你什么时候回来 x 在功能 f,地址的副本将传递回调用者。来电者可以打电话 free 在那个地址上。


1
2017-08-09 22:33





是的,你需要自由,但是当你这样做时它已经被释放了 free(a); 在 main (以来 a 被赋予相等的 x 在线 a = f();)。


1
2017-08-09 22:35





x 退出函数后会被销毁。的价值 x 是指向动态分配的对象的地址。退出函数后,该对象仍然存在。

要释放动态对象,您必须传递值 x 这是由...返回的 f 功能 free 功能。


1
2017-08-09 22:39



我们该如何实现这一目标? - sivaram
@sivaram已经在OP的代码片段中完成了 free(a) 呼叫。 - ouah


你打电话时 malloc 它分配内存并返回该内存块的初始地址。

在您的情况下,您将此地址返回给被调用者,现在被调用者main负责解除分配。

解除内存块所需的唯一内容是初始地址,AFIK负责分配/释放内存它使用相当复杂的算法,但程序只需要跟踪初始内存地址。这个地址可以像任何其他整数值一样存储或移动,因为在32位系统中,它只是一个int值。


0
2017-08-09 22:39





你的代码工作得很好,你获释了 a 这是f的字符串malloced。


0
2017-08-09 22:40