Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.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_Linux_Memory_Memory Management_Memory Leaks - Fatal编程技术网

在C中退出之前使用指向清理的指针的全局数组

在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

我有一个小程序,其中包含一个需要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
为了使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会抱怨内存泄漏,因此如果可能,最好手动释放内存,如果这样做的话