C 用信号清除动态分配的数据
使用signal时,使用C中的C 用信号清除动态分配的数据,c,memory-management,malloc,signals,C,Memory Management,Malloc,Signals,使用signal时,使用C中的free()动态分配数据清理的正确方法是什么 有一个共享内存的例子,使用的解决方案是声明全局变量,但看起来不是很干净和安全 这是一个示例代码,其中动态分配了一个结构数组,但没有正确清理 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> typedef struct { int val; } mystr
free()
动态分配数据清理的正确方法是什么
有一个共享内存的例子,使用的解决方案是声明全局变量,但看起来不是很干净和安全
这是一个示例代码,其中动态分配了一个结构数组,但没有正确清理
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
typedef struct {
int val;
} mystruct_t;
void sigquit(int sig) {
signal(sig, SIG_IGN);
printf("Child killed\n");
// Clear the dynamic allocated data inside
// the signal quit method
//
// int i;
// for (i = 0; i < n; i++) {
// free(struct_a[i]);
// }
// free(struct_a);
exit(0);
}
int
main()
{
int n = 10;
/* dynamic allocated array of structure */
mystruct_t **struct_a = generatearray(n);
pid_t pid = fork();
if (pid == 0) {
printf("Child process. My pid is %d and my parent's id is %d.\n",
getpid(), getppid());
if (signal(SIGQUIT, sigquit) == SIG_ERR) {
printf("SIGINT install error\n");
exit(1);
}
while(1);
}
else {
printf("Parent process. My pid is %d and my parent's id is %d.\n",
getpid(), pid);
sleep(1);
kill(pid, SIGQUIT);
sleep(5);
}
return 0;
}
#包括
#包括
#包括
#包括
类型定义结构{
int-val;
}我的结构;
无效sigquit(内部sig){
信号(信号,信号);
printf(“儿童死亡”);
//清除内部的动态分配数据
//信号退出方法
//
//int i;
//对于(i=0;i
您将使用哪种方法来解决此问题?让信号处理程序设置一个类型为
sig\u atomic\t
的变量。在您的常规代码中,定期检查要设置的变量,如果是,则完全关闭。如果需要,清洁关机必须设计成一个软件。根据POSIX,无论是malloc()
还是free()
还是任何其他高级内存分配函数都是信号安全的(mmap()
和friends都是)。您无法在信号处理程序中安全地调用它们,因为从信号处理程序调用它们时不需要它们
典型的解决方法是在信号处理程序中设置一个标志,以清除内存。程序的主循环定期检查此标志,并在发现标志已设置时执行所需的操作。使用此变量的类型
sig_atomic\u t
,并将其声明为volatile
,以获得最大的安全性。与共享内存不同,大多数其他资源(如套接字和malloced内存)在程序退出之前不需要清理。这是因为在进程终止后,它们无论如何都会被清除
设置将在主循环中处理的标志对于其他信号来说是个好主意,但是对于
SIGQUIT
将不会像预期的那样工作,因为在调用信号处理程序后,您的进程将已经终止。在实际代码中,子进程可能会使用select
或其他类似机制产生事件循环。然后,一般的过程是让信号处理程序只设置一个标志。然后,事件循环将检测到这一点,并执行流程清理并在该点退出(在信号处理程序之外)。