【问题标题】:How to free pointer memory inside a function?如何释放函数内的指针内存?
【发布时间】:2022-09-27 21:05:56
【问题描述】:

我对指针的使用不熟悉,我正在尝试编写一个程序来学习使用它们。我有一个问题要问你。我有一个文件lib.h,在里面我定义了所有必要的函数。在这个文件中,我有一个简单的数据struct

struct Slave
{
    char **all_samples;
    int number_of_samples;
    char **last_samples;
    int *RSSI;
    int *AGC;
    int *AUTH;
};

如您所见,该结构的成员是指针(指向 int 的指针,指向 ecc 指针的指针)。在同一个文件中,我有几个函数。为了简洁起见,考虑其中之一。在这个函数中,我从一个文件中读取了几行并将它们放入数组字符串all_samplesi 是先前正确计算的行数):

struct Slave *read_slaves_file(char *file_path, char *slave)
{
    ...

    struct Slave *slave_ptr = malloc(sizeof(struct Slave *));
    slave_ptr->all_samples = malloc(i * sizeof(char *));
    slave_ptr->all_samples = all_samples;

    return slave_ptr;
}

我省略了代码中不相关的部分(我的问题更具理论性,我的程序中没有错误)。如您所见,我返回一个指向结构的指针,因此,在 main 内部:

#include \"lib.h\"

int main(){

    struct Slave *slave_1 = malloc(sizeof(struct Slave *));
    slave_1 = read_slaves_file(FILE_PATH, SLAVE_1);

    return 0;
}

一切似乎都很好......但是,我有一个疑问。在前一个函数内部动态分配的所有内存:

struct Slave *slave_ptr = malloc(sizeof(struct Slave *));
slave_ptr->all_samples = malloc(i * sizeof(char *));

应该在哪里解除分配?是否应该解除分配?我想在返回指针之前我不能释放内存。那么,该怎么做呢?

  • \"我的程序没有错误)。如您所见,我返回一个指向结构的指针,因此,在 main:\" slave_1 = malloc(sizeof(struct Slave *)); slave_1 = /* blatant bug here */
  • 添加一个 free_slaves 它将释放从属指针并在您不再需要指针时调用它。
  • 当然可以,但我的问题是:我必须释放的唯一内存是在主内存中分配的指针内存吗?只为他们?如您所见,在函数 read_slaves_file 内部,我为结构分配内存,为其字段分配内存。这个内存分配不需要deallocate?
  • 您应该以相反的顺序将每个malloc()free() 匹配。当您释放结构本身时,不会自动释放具有分配的struct 成员。
  • 是的,事实上我的问题是关于这个的。我怎样才能释放函数内的 malloc 然后我将指针返回到结构?

标签: arrays c pointers memory struct


【解决方案1】:

我的程序没有错误

你有很多错误。

  • struct Slave *slave_1 = malloc(sizeof(struct Slave *));
    slave_1 = read_slaves_file(FILE_PATH, SLAVE_1);
    

    这会重新分配slave_1,从而造成内存泄漏。在调用者和函数内部分配内存是没有意义的。下定决心在哪里进行分配。

  • malloc(sizeof(struct Slave *)) 这应该是 malloc(sizeof(struct Slave)) 或者如果您更喜欢 malloc(sizeof(*slave_1))。相同的错误存在于多个地方。

  • slave_ptr->all_samples = malloc(i * sizeof(char *));
    slave_ptr->all_samples = all_samples;

    和以前一样的错误。通过使用赋值运算符,您可以复制指针或复制数据。除非您更改操作数的类型,否则它不能同时做这两件事。在这一点上,我将退出动态分配并研究指针是如何工作的,特别是非正式地称为“软拷贝”与“硬拷贝”的东西。


应该在哪里解除分配?

最好的选择总是让调用者进行分配并让他们提供一个指向缓冲区的指针,以便函数填满。这将分配与算法分开。但是,这可能并不总是一种选择。

另一个好的设计是让分配某些东西的代码模块也负责清理自己的烂摊子。因此,如果您的 lib 提供了一个返回指向动态分配数据的指针的函数,那么同一个 lib 还应该提供另一个函数来清理该数据。

一些设计不太好的函数返回一个指针并期望调用者清理它(例如参见 POSIX getline)。这是有问题的,但如果你正确记录调用者负责清理,你就可以侥幸逃脱。

【讨论】:

  • 谢谢你的回答,你是对的,我意识到我在内存分配中做的概念错误。但是有一件事我无法理解......在所有内存分配之后,我将指针返回到结构。至此,函数终止。如何释放函数分配的内存?我想在我返回指针之前我不能这样做......那么,怎么做呢?
  • 释放 main 中的指针是否足够?
  • @LearningC 正如此答案中所写,您有 3 个不同的选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-23
  • 2016-03-30
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 2013-10-20
相关资源
最近更新 更多