在C中退出之前使用指向清理的指针的全局数组
我有一个小程序,其中包含一个需要malloc的变量:在C中退出之前使用指向清理的指针的全局数组,c,linux,memory,memory-management,memory-leaks,C,Linux,Memory,Memory Management,Memory Leaks,我有一个小程序,其中包含一个需要malloc的变量: char **v; v = (char**)malloc(sizeof(char *) * MAX_EVENTS); for (int i = 0; i < MAX_EVENTS; i++) v[i] = (char *)malloc(MAX_NAME_SIZE); char**v; v=(char**)malloc(sizeof(char*)*MAX_事件); 对于(int i=0;i
char **v;
v = (char**)malloc(sizeof(char *) * MAX_EVENTS);
for (int i = 0; i < MAX_EVENTS; i++)
v[i] = (char *)malloc(MAX_NAME_SIZE);
char**v;
v=(char**)malloc(sizeof(char*)*MAX_事件);
对于(int i=0;i
为了使Valgrind高兴,避免内存泄漏,我设置了终止信号的处理程序。此处理程序将在退出之前释放该分配,并终止子进程
static void term_handler() {
if (v != NULL) {
for (int i = 0; i < MAX_EVENTS; i++) {
if (v[i] != NULL)
free(v[i]);
}
free(v);
}
for (int i = 0; i < MAX_PROCS; i++)
if (children[i])
kill(children[i], SIGTERM);
exit(EXIT_SUCCESS);
}
static void term_handler(){
如果(v!=NULL){
对于(int i=0;i
要从处理程序访问v
,我将其作为全局变量children
是一个静态数组pid\u t children[MAX\u PROCS]代码>但也可能是malloced
从处理程序访问这些分配的最干净的方法是什么?不建议使用全局变量,但内存泄漏和未正确终止的程序也不建议使用全局变量。
我应该保留一个指向分配的指针数组作为全局变量吗?或者我应该避免处理意外信号吗?信号处理程序很棘手,因为它们是异步调用的,因此在信号处理程序中只能安全地调用。特别是,从信号处理程序中分配或释放内存是不允许的(就像调用一样!),所以不要这样做
但是,如果您想确保内存被释放(*),可以让信号处理程序“告诉”程序的主线程该退出了。然后,主线程可以中断其事件循环,释放内存,并执行退出之前通常会执行的任何其他清理工作
那么问题就变成了,信号处理程序如何安全地告诉主线程执行受控/优雅的退出
如果主线程正在运行一个按照固定计划执行的事件循环(例如,每隔这么多毫秒),那么它可能与声明一个全局变量一样简单(例如,volatile bool plessequitnow=false;
主线程在其事件循环的每次迭代中进行测试,并让信号处理程序将该变量设置为不同的值。然后主线程将在其下一次迭代中看到更改的变量,并通过中断事件循环进行响应
另一方面,如果主线程的事件循环是基于事件的(例如,它在内部或类似情况下被阻塞,调用在一段不确定的时间内不会返回),则唤醒主线程的另一种方法是在程序启动时创建or,并让主线程监视两个文件描述符中的一个以查看read ready状态。然后,当信号处理程序运行时,它可以发送()另一个文件描述符上的一个字节,它将导致第一个文件描述符指示ready for read状态。主线程可以通过中断其事件循环并正常退出来响应ready for read状态
除了避免异步信号不安全调用之外,这种方式的好处是,您只有一个关闭/清理路径要测试/调试/维护,而不是两个
(*)当然,在任何现代操作系统上,内存都会通过操作系统的进程清理例程得到释放;但是valgrind会抱怨内存泄漏,因此如果可能,最好手动释放内存,如果只是为了让您可以使用valgrind查找“真实的”每次都不必对一堆误报进行排序就可以泄漏内存。信号处理程序很棘手,因为它们是异步调用的,因此只有一个可以从信号处理程序中安全调用。特别是,从信号处理程序中分配或释放内存是不允许的(就像调用一样!),所以不要这样做
但是,如果要确保释放内存(*),可以让信号处理程序“告诉”程序的主线程该退出了。然后,主线程可以跳出事件循环,释放内存,并在退出之前执行任何其他正常清理工作
那么问题就变成了,信号处理程序如何安全地告诉主线程执行受控/优雅的退出
如果主线程正在运行一个按照固定计划执行的事件循环(例如,每隔这么多毫秒),那么它可能与声明一个全局变量一样简单(例如,volatile bool plessequitnow=false;
主线程在其事件循环的每次迭代中进行测试,并让信号处理程序将该变量设置为不同的值。然后主线程将在其下一次迭代中看到更改的变量,并通过中断事件循环进行响应
另一方面,如果主线程的事件循环是基于事件的(例如,它在内部或类似情况下被阻塞,调用在一段不确定的时间内不会返回),则唤醒主线程的另一种方法是在程序启动时创建or,并让主线程监视两个文件描述符中的一个以查看read ready状态。然后,当信号处理程序运行时,它可以发送()另一个文件描述符上的一个字节,它将导致第一个文件描述符指示ready for read状态。主线程可以通过中断其事件循环并正常退出来响应ready for read状态
除了避免异步信号不安全调用之外,这种方式的好处是,您只有一个关闭/清理路径要测试/调试/维护,而不是两个
(*)当然,在任何现代操作系统上,内存都会通过操作系统的进程清理例程得到释放;但是valgrind会抱怨内存泄漏,因此如果可能,最好手动释放内存,如果这样做的话