2017-10-04 46 views
0

我目前有一个typedef指针函数,它不会指向任何导致分段错误(核心转储)的东西。我试图想出一个解决方案来避免它,但目前还没有想到。函数指针指向什么 - 我如何避免这种情况?

我的代码:

typedef void (*MenuFunction)(System*); 

int main(int argc, char ** argv) 
{ 
    ... 
    /* While loop for my menu */ 
    while(1) 
    { 
     printf("Main Menu\n"); 
     printf("%s\n", menu[0].text); 
     printf("%s\n", menu[1].text); 
     printf("%s\n", menu[2].text); 
     printf("Select your option (1-3): "); 
     (*getMenuChoice(menu))(&system); 
    } 
} 

/* Function that points to the menu function */ 
MenuFunction getMenuChoice(MenuItem * menu) 
{ 
    MenuFunction function = NULL; 
    char select[50]; 
    fgets(select, 50, stdin); 
    if(select[strlen(select)-1] == '\n') 
    {  
     switch(select[0]) 
     { 
      case '1': 
       function = menu[0].function; 
       break; 
      case '2': 
       function = menu[1].function; 
       break; 
      case '3':  
       function = menu[2].function; 
       exit(0); 
       break; 
      default: 
       printf("Invalid option\n"); 
     } 
    } 
    else 
    { 
     readRestOfLine(); 
     printf("Error: buffer overflow. Please try again, entering less data"); 
    } 
    return function; 
} 

编辑:

现在,我想出了一个解决方案是创建一个什么也没有的功能,所以我可以有指向一些功能。我不认为这是理想的,但它会在短期内完成。

void skip() 
{ } 
+0

它是在建设吗? – MayurK

+3

也许你应该在使用之前检查'getMenuChoice'返回的内容?当你有一个可以返回空指针的函数时,总是一件好事。 –

+1

这需要[mcve]。 – Yunnosch

回答

2

管理一个大战略所有的指针(数据函数以及函数指针)是:让它们总是指向有效的东西,或者是空的。那就是:

  1. 当你声明一个指针变量时,总是初始化它,要么指向有效的东西,要么指向NULL。
  2. 在使用指针之前,请确保它不是NULL。
  3. 当你做任何会使指针无效的事情时,将它设回NULL。

在你的情况,你下面的规则已经1,当你初始化

MenuFunction function = NULL; 

所以你getMenuChoice()函数返回NULL,如果选择是无效的。没有错,这是一种常见的模式。

您还需要做的就是现在你已经有了

(*getMenuChoice(menu))(&system); 

这是一种拗口的遵守规则2.什么:你叫getMenuChoice(),然后立即调用它返回一个指针的函数至。此拆分成几行:

MenuFunction fp; 
fp = getMenuChoice(menu); 
if(fp == NULL) 
    fprintf(stderr, "invalid choice\n"); 
else 
    (*fp)(&system); 

在这里,我们在一个新的变量fp捕捉getMenuChoice的返回值,而我们测试,以确保它不是NULL我们称之为前。

[P.S.在你的情况下,你不需要担心我的规则3.]

1

为了避免“本”赛格故障事件:

检查的typedef的实例包含非NULL通过的typedef实例调用之前

相关问题