将参数传递给atexit()

4

在我的程序中,我使用了一个静态变量(没有其他方法),问题是需要在退出时释放它。

如果不将此变量声明为全局变量,该怎么做呢?

我考虑使用atexit函数,但似乎不能接受参数。有没有什么办法可以传递我的变量呢?

谢谢。


1
不够明确的是:静态变量是全局的,它们不需要由应用程序进行“释放”。由于您没有直接调用atexit,那么您将如何传递任何内容?我嗅到一个XY问题。 - too honest for this site
4个回答

5

我不确定它是否符合您的要求,但是我会将静态变量作为文件范围的静态变量,在一个源文件中关闭,类似于以下内容:

static char *my_static_variable = NULL;

static void my_cleanup_function()
{
    free(my_static_variable);
}

void my_initialization_function()
{
    my_static_variable = malloc(10);
    atexit(my_cleanup_function);
}

也就是说,my_static_variablemy_cleanup_function 只在这个源文件中可见,它们不是全局变量。

顺便提一下,通常情况下,在程序退出时不需要释放用 malloc 分配的内存。任何你分配的内存都会被操作系统自动释放,当它释放进程所使用的内存时。


1
是的,但这是通过使用全局变量实现的,而我不愿意这样做。我可以在 main 函数返回之前释放全局变量,它会产生相同的效果。[编辑]:与上面相同,不幸的是您正在使用我不愿意使用的全局变量。是的,系统有效地回收了内存,但这是一个学校项目,它需要看起来漂亮! - Ra'Jiska
2
@Ra'Jiska 我明白。我已经澄清了我的答案,解释说你可以将它设置为文件范围的静态变量,这并不是真正的全局变量。 - Steve Summit
1
没错,似乎没有36种正确的方法,我会认真考虑并看看是否这是最好的方式。谢谢。 - Ra'Jiska

1

退出状态正是我想要访问的。可惜这不是 POSIX,只是 glibc 的扩展。但是 newlib 3.0.0.20180226 有它 :-) - Ciro Santilli OurBigBook.com

1
我假设你所说的“全局”是指你不想使用文件作用域变量,“静态”是指函数中的静态局部变量而不是其他19个含义之一。由于你没有给出足够的上下文,因此肯定有更清晰的解决方案,但你可以向声明该变量的函数添加参数并执行以下操作:
void
foo(int exit_flag, ...)
{ 
        static int * x = NULL
        if( exit_flag ){
                /* cleanup */
                free(x);
                return;
        }
        ...
}

始终在 exit_flag == 0 的情况下调用 foo,除非你在退出处理程序中设置了 exit_flag。

由于某些原因,我还没有考虑过这个。我会看看它是否可以与我的代码设计配合使用。谢谢。 - Ra'Jiska
而不是这个词的其他19个含义之一... 呵呵,不,它只是在C++中过度载入了那么多 :) - ThingyWotsit

0
如何在不将该变量声明为全局变量的情况下实现此目标?
“static”存储类变量是全局变量--它们只是未导出到链接器,因此只能在同一翻译单元中引用。
我在考虑使用“atexit”函数,但似乎无法接受参数。有没有什么技巧可以传递我的变量?
是的,只需使用“atexit”注册处理程序即可:
static void* foo = NULL;

static void handler () {
  free(foo);
}

...

atexit(handler);

如果你要退出程序,其实不需要手动释放内存。系统会自动清理。而且也不能保证你的 atexit 处理函数一定会被调用(例如 SIGKILL 信号)。


OP没有说“static”,而是静态的。 - too honest for this site
1
另外,_exit() 不会调用使用 atexit() 注册的函数。还有其他类似的避免清理的方法。 - Jonathan Leffler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接