C语言函数指针的问题

函数和函数指针用来控制程序的执行顺序,但是它们可能会被误用,导致不可预期的行为。考虑下面的getSystemStatus函数的使用,它返回反应系统状态的整数:

int getSystemStatus() {
    int status;
    ...
    return status;
}

下面是判断系统状态是否为0的最好方法:

if(getSystemStatus() == 0) {
    printf("Status is 0\n");
} else {
    printf("Status is not 0\n");
}

接下来这个例子中,忘记了加上括号,这段代码不会正常执行:

if(getSystemStatus == 0) {
    printf("Status is 0\n");
} else {
    printf("Status is not 0\n");
}

系统会一直执行else分支,在逻辑表达式中,我们把函数的地址和0作比较,而不是调用函数后比较返回值和0。记住,只用函数名本身时返回的是函数的地址。

一个类似的错误是直接使用函数返回值,而不会将它的结果和其他值进行比较,这样会返回地址然后计算真假,而函数的地址不大可能是0,结果就是返回的地址计算为真,因为C把非0值都作为真:

if(getSystemStatus) {
    // 永远为真
}

我们应该像下面这样写函数调用来判断状态是否为0:

if(getSystemStatus()) {

如果函数和函数指针的签名不同,不要把函数赋给函数指针,这样会导致未定义的行为,一个误用的例子如下所示:

int (*fptrCompute)(int,int);
int add(int n1, int n2, int n3) {
    return n1+n2+n3;
}

fptrCompute = add;
fptrCompute(2,5);

我们试图只用两个参数调用add函数,而该函数期望的是三个参数,代码能编译,但是输出是不确定的。

函数指针可以执行不同的函数,这取决于分配给它的地址。比如说,我们可能想为一般的操作使用printf函数,但是有时候为了打印特定日志需要换成别的函数,那么可以像下面这样声明并使用函数指针:

int (*fptrIndirect)(const char *, ...) = printf;
fptrIndirect("Executing printf indirectly");

攻击者可能用缓冲区溢出来覆写函数指针的地址,如果发生这类攻击,控制可能会转移到内存中的任意位置。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程