Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 释放分配的内存_C_Malloc_Free - Fatal编程技术网

C 释放分配的内存

C 释放分配的内存,c,malloc,free,C,Malloc,Free,通用条款4.4.5 c89 我有一个名为create_object的函数,为全局结构分配内存。我有一个名为destroy_object的函数,我检查指针是否为null,然后释放。以防万一,我会释放尚未分配的内存。然而,我已经通过连续两次调用销毁_对象来测试了这一点。但是,我在第二次调用时得到一个堆栈转储。但是,我确信它不会被释放,因为我已经将指针指定为NULL。所以它应该跳过free函数 static struct Config_t { char protocol[LINE_SIZE];

通用条款4.4.5 c89

我有一个名为create_object的函数,为全局结构分配内存。我有一个名为destroy_object的函数,我检查指针是否为null,然后释放。以防万一,我会释放尚未分配的内存。然而,我已经通过连续两次调用销毁_对象来测试了这一点。但是,我在第二次调用时得到一个堆栈转储。但是,我确信它不会被释放,因为我已经将指针指定为NULL。所以它应该跳过free函数

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;
}
========================================最终编辑==== 静态结构配置{ 字符协议[行大小]; 字符模式[行大小]; }app_cfg[1]{{,'',''}


现在我没有使用malloc和free。

在Cygwin下的gcc 3.3.3中使用这段代码对我来说是正确的,只要我调用它两次。您没有告诉我们您在这些函数之外做了什么,所以请先看一下,例如,您可能在调用之间意外地为app_cfg分配了一个垃圾非空值。此外,如果您没有使用“大名鼎鼎”的编译器,这可能是一个编译器错误(例如,它可能在编译时过于乐观,并假设您永远不会传递NULL来销毁配置)。试着输入以下内容:

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" );
        }
}

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

在Cygwin下的gcc 3.3.3中使用这段代码,在我两次调用它时,对我来说是正确的。您没有告诉我们您在这些函数之外做了什么,所以请先看一下,例如,您可能在调用之间意外地为app_cfg分配了一个垃圾非空值。此外,如果您没有使用“大名鼎鼎”的编译器,这可能是一个编译器错误(例如,它可能在编译时过于乐观,并假设您永远不会传递NULL来销毁配置)。试着输入以下内容:

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" );
        }
}

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

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

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

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

static struct Config_t {
    char protocol[LINE_SIZE];
    char mode[LINE_SIZE];
} app_cfg;
您仍然可以提供一个
create
destroy
,它
memset
将结构设置为零,但即使这样也可能不需要:

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

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

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

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

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

static struct Config_t {
    char protocol[LINE_SIZE];
    char mode[LINE_SIZE];
} app_cfg;
您仍然可以提供一个
create
destroy
,它
memset
将结构设置为零,但即使这样也可能不需要:

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

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

在我看来这很好,您能发布使用此指针并调用
create\u object
destroy\u config
的代码吗?此外,如果您想立即将分配给
app\u cfg
的内存初始化为0s,您可以将
malloc
memset
调用组合成一个
calloc
调用。另外,在空指针上使用
free
也很好。将空指针传递到
free()
是一个安全的禁止操作,因此您不需要在
destroy\u config()
中进行空签入。您是否能够通过gdb运行代码,并在SIGSEGV引发后查看回溯?它是否指向程序中的任何其他位置?我觉得这很好,您可以发布使用此指针并调用
create\u object
destroy\u config
的代码吗?此外,如果您想立即将分配给
app\u cfg
的内存初始化为0s,您可以将
malloc
memset
调用组合成一个
calloc
调用。另外,在空指针上使用
free
也很好。将空指针传递到
free()
是一个安全的禁止操作,因此您不需要在
destroy\u config()
中进行空签入。您是否能够通过gdb运行代码,并在SIGSEGV引发后查看回溯?它是否指向程序中的任何其他位置?
memset
肯定不需要。因为它是静态的,所以保证为0填充。“而且销毁似乎也没有什么意义。”马修,我想的更多的是你希望在重新使用之前将其清除,而不是最初使用。但是,即使在创建/销毁时没有清除,优秀的程序员也不应该编写受遗留值影响的代码,因此我的“可能不需要”注释。我已经更改了源代码,并按照您的建议执行了操作。只有一个问题。在我的源代码中,我只需要struct变量的一个副本(堆栈级别,静态全局)。我想如果我创建了许多这种结构的对象,并希望它们在应用程序的生命周期中都可用。我想这是使用malloc的一个很好的理由?关于可能的重用,你有一个观点(尽管我不知道需要一个方法)。@ant2009:是的。如果您需要多个副本,您可以将它们malloc并从
create\u which
返回指针。然后,有一个
destroy\u which
来清理是很有用的,因为这意味着您可以随意更改代码而不影响API。
memset
肯定是不需要的。因为它是静态的,所以保证为0填充。“而且销毁似乎也没有什么意义。”马修,我想的更多的是你希望在重新使用之前将其清除,而不是最初使用。但是,即使在创建/销毁时没有清除,优秀的程序员也不应该编写受遗留值影响的代码,因此我的“可能不需要”注释