【问题标题】:freeing allocated memory释放分配的内存
【发布时间】:2011-05-13 15:48:39
【问题描述】:

gcc 4.4.5 c89

我有一个名为 create_object 的函数,我在其中为全局结构分配内存。我有一个名为destroy_object 的函数,我在其中检查指针是否为空,然后释放。以防我释放尚未分配的内存。但是,我已经通过连续两次调用destroy_object 对此进行了测试。但是,我在第二次调用时得到了堆栈转储。但是,我确信它不会释放,因为我已将指针分配给 NULL。所以它应该跳过免费功能。

static struct Config_t {
    char protocol[LINE_SIZE];
    char mode[LINE_SIZE];
} *app_cfg = NULL;

int create_object()
{
    app_cfg = malloc(sizeof *app_cfg);
    memset(app_cfg, 0, sizeof *app_cfg);
}

void destroy_config()
{
    /* Check to see if the memory is ok to free */
    if(app_cfg != NULL) {
        free(app_cfg);
        app_cfg = NULL;
    }
}

非常感谢您的任何建议,

================== 编辑========== 基本上我在我的主函数中有一个对 create_object() 的调用,我做了一些处理,然后调用了 destory_object。

int main(void)
{
    create_object();

    /* Do some processing on the structure */

    destroy_object();

    return 0;
}

==========================最终编辑==== 静态结构 Config_t { 字符协议[LINE_SIZE]; 字符模式[LINE_SIZE]; } app_cfg[1] {{"", ""}};

现在我没有使用 malloc 和 free。

【问题讨论】:

  • 这对我来说很好,你能发布使用这个指针并调用create_objectdestroy_config 的代码吗?此外,如果您想立即将分配给app_cfg 的内存初始化为0,您可以将mallocmemset 调用合并为一个calloc 调用。此外,空指针上的free 非常好。
  • 将空指针传递给free() 是一个安全的空操作,因此您不需要在destroy_config() 中进行空检查。
  • 你能通过gdb运行代码并查看SIGSEGV引发后的回溯吗?它是否指向您程序中的任何其他位置?

标签: c malloc free


【解决方案1】:

我只有一个建议。不要为此分配内存,这是浪费精力。

由于app_cfg 是一个文件级变量,因此一次只能有一个副本,因此分配和取消分配它没有什么意义。

只需将其创建为静态非指针并使用它:

static struct Config_t {
    char protocol[LINE_SIZE];
    char mode[LINE_SIZE];
} app_cfg;

您仍然可以提供createdestroy 其中memset 的结构为零,但即使这样也可能不需要:

void create_object (void) {
    memset(&app_cfg, 0, sizeof(app_cfg));
}

void destroy_config (void) {
    memset(&app_cfg, 0, sizeof(app_cfg));
}

【讨论】:

  • memset 绝对不需要。它保证为 0 填充,因为它是静态的。而且破坏似乎也没有意义。
  • @Matthew,我想更多的是您希望在重用之前清除它而不是初始使用的情况。但是,即使它在创建/销毁时没有被清除,体面的编码人员也不应该编写受遗留值影响的代码,因此我的“可能不需要”评论。
  • 我已经更改了我的源代码并按照您的建议完成了。就一个问题。在我的源代码中,我只需要结构变量的一份副本(堆栈级别,静态全局)。我想如果我正在创建这种结构的许多对象并希望它们在应用程序的生命周期内可用。我想这是使用 malloc 的一个很好的理由?
  • 您对可能的重用有所了解(尽管我不知道需要一种方法)。
  • @ant2009:是的。如果您想要多个副本,您可以将它们 malloc 并从 create_whatever 返回指针。然后使用destroy_whatever 进行清理会很有用,因为这意味着您可以随意更改该代码而不会影响 API。
【解决方案2】:

当我调用它两次时,在 Cygwin 下将此代码与 gcc 3.3.3 一起使用对我来说可以正常工作。你没有告诉我们你在这些功能之外做什么,所以先看看那里,例如也许您不小心在调用之间为 app_cfg 分配了一个垃圾非 NULL 值。此外,如果您没有使用“大牌”编译器,则有可能这是一个编译器错误(例如,它可能在编译时过于乐观,并假设您永远不会将 NULL 传递给 destroy_config)。尝试输入类似的内容:

void destroy_config()
{

    /* Check to see if the memory is ok to free */
    if(app_cfg != NULL) {
        printf("not null\n" );
        free(app_cfg);
        app_cfg = NULL;
    }else{
        printf("null\n" );
        }
}

看看它是否真的“知道”它何时为空。

【讨论】:

  • 释放NULL没有错,所以这不是bug的来源。此外,它几乎肯定不是编译器错误。
猜你喜欢
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
相关资源
最近更新 更多