用信号清除动态分配的数据

标签 c memory-management malloc signals

在 C 中使用信号时,使用 free() 动态分配数据的正确方法是什么?

Here有一个共享内存的例子,使用的解决方案是声明全局变量,但似乎不是很干净和安全。

这是一个示例代码,其中包含一个动态分配的结构数组,但未正确清理

#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;
}

你会用什么方法来解决这个问题?

最佳答案

根据 POSIX,malloc()free() 以及任何其他高级内存分配函数都不是信号安全的(mmap( ) 和 friend 们虽然)。您不能在信号处理程序中安全地调用它们,因为它们不需要在被信号处理程序调用时继续存在。

典型的解决方法是在信号处理程序中设置一个标志,指示应清除内存。程序的主循环会定期检查此标志,并在发现已设置标志时执行所需的操作。为该变量使用类型 sig_atomic_t 并将其声明为 volatile 以获得最大的安全性。

关于用信号清除动态分配的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34445242/

相关文章:

c++ - C++中使用成员函数删除对象

c - munmap_chunk() : invalid pointer in c

c - 具有包含可变大小对象的结构的 Malloc

c - Malloc 和结构

c - 堆管理器的空闲列表存储在进程的地址空间中的什么位置?

c - 查找满足 i < j 且 A[i]**A[j] > A[j]**A[i] 的对 (A[i], A[j]) 的数量

c - fread (.txt) 中的奇怪符号

c - 在 C 中将打开的文件作为参数传递

c++ - Eclipse错误: Unresolved Inclusion

C++ 避免两次删除内存