将sigaction声明为值类型的指针类型

时间:2011-04-23 11:59:12

标签: c signals

gcc (GCC) 4.6.0 20110419 (Red Hat 4.6.0-5)

我正在使用sigaction,当我将信号hanlder函数分配给sa_handler时,我得到了堆栈转储。

这是我使用指针类型做的:

struct sigaction *new_act = NULL;

new_act->sa_handler = signal_handler; /* This line produces the stack dump */

sigaction(SIGINT, new_act, NULL);

这是我使用值类型所做的:

struct sigaction new_act;

new_act.sa_handler = signal_handler; /* No problem here */

sigaction(SIGINT, &new_act, NULL);

使用指针类型的值类型有什么区别?

非常感谢任何建议,

2 个答案:

答案 0 :(得分:2)

struct sigaction *new_act = NULL;

这只会创建一个指向 struct sigaction的类型的变量。它根本不会创建struct sigaction。没有为该结构的字段分配内存,只足以存储这样的结构的地址。

如果你想使用指针,你需要使用malloc自己为结构分配内存,例如:

struct sigaction *new_act = malloc(sizeof(struct sigaction));

并且在不再使用时请记住free

代码的第二个版本正确创建了struct sigaction类型的对象,因此您可以直接与其进行交互。

答案 1 :(得分:1)

这里的错误是指向程序员的一个非常普遍的误解。如果我没弄错的话,你已经根据sigaction函数接受指针参数的事实创建了一个带指针类型的变量。但论证的重点是指向,即包含信号处理信息的结构。将参数传递给函数时,只需要一个表达式,其类型与函数参数类型兼容,不一定是该类型的变量。例如,一些初学者可能倾向于写:

struct sigaction new_act;
struct sigaction *new_act_ptr = &new_act;
/* ... fill in new_act here ... */
sigaction(SIGINT, new_act_ptr, NULL);

但是这里的指针变量完全没用。表达式&new_act本身已经具有正确的类型,因此您可以这样做:

struct sigaction new_act;
/* ... fill in new_act here ... */
sigaction(SIGINT, &new_act, NULL);