函数指针指向什么 - 我该如何避免这种情况?

时间:2017-10-04 13:05:45

标签: c segmentation-fault function-pointers

我目前有一个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()
{ }

2 个答案:

答案 0 :(得分:2)

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

  1. 当你声明一个指针变量时,总是初始化它,要么指向有效的东西,要么指向NULL。
  2. 在使用指针之前,请确保它不是NULL。
  3. 当您执行任何会使指针无效的操作时,请将其设置为NULL。
  4. 在您的情况下,您在初始化时已经遵循规则1

    MenuFunction function = NULL;
    

    因此,如果选择无效,则getMenuChoice()函数将返回NULL。没错,这是一种常见的模式。

    您需要另外做的是遵守规则2.现在您已经

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

    这是一种满口:你调用getMenuChoice(),然后立即调用它返回指针的函数。将其拆分为几行:

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

    在这里,我们在一个新变量getMenuChoice中捕获fp的返回值,并且在我们调用之前测试以确保它不是NULL。

    [P.S。在您的情况下,您不必担心我的规则3.]

答案 1 :(得分:1)

避免'this'seg错误事件:

在通过typedef实例调用函数之前,检查typedef的实例是否包含NULL以外