MST

星途 面试题库

面试题:C语言指针访问结构体和联合体区别之复杂场景

假设有一个结构体 `struct complex { int a; union { float b; double c; } u; }`,使用指针来访问这个结构体及其联合体成员。现在需要编写一个函数 `void process(struct complex *ptr)`,在函数中根据联合体成员的类型(假设通过一个额外的标志位 `int flag` 判断,`flag` 为0表示 `float`,为1表示 `double`),对联合体成员进行不同的计算并返回结果。解释指针在这样复杂嵌套结构下访问成员的潜在风险及如何规避。
14.0万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#include <stdio.h>

struct complex {
    int a;
    union {
        float b;
        double c;
    } u;
};

double process(struct complex *ptr, int flag) {
    if (flag == 0) {
        return (double)(ptr->u.b) * ptr->a;
    } else if (flag == 1) {
        return ptr->u.c * ptr->a;
    }
    return 0;
}

int main() {
    struct complex num;
    num.a = 2;
    num.u.b = 3.5;
    printf("Result with flag 0: %lf\n", process(&num, 0));

    num.u.c = 4.5;
    printf("Result with flag 1: %lf\n", process(&num, 1));

    return 0;
}

指针在复杂嵌套结构下访问成员的潜在风险及规避方法

  1. 类型不匹配风险

    • 风险:如果通过指针访问联合体成员时,使用了错误的类型(例如,原本应该是 float 类型却按 double 类型访问),会导致未定义行为。因为 floatdouble 在内存中的存储方式不同,错误的访问会读取到错误的数据。
    • 规避:通过额外的标志位(如题目中的 flag)来明确当前联合体中实际存储的数据类型,确保使用正确的类型进行访问。
  2. 空指针解引用风险

    • 风险:如果传递给 process 函数的指针 ptr 是一个空指针,对空指针进行解引用操作(如 ptr->aptr->u.b)会导致程序崩溃。
    • 规避:在函数开始处对指针进行有效性检查,例如 if (ptr == NULL) return 0;
  3. 内存释放问题

    • 风险:如果结构体是在堆上分配的内存,在释放内存时,如果没有正确处理指针,可能会导致内存泄漏。例如,在释放结构体指针后,没有将指针置为 NULL,可能会导致悬空指针,后续对该指针的操作会导致未定义行为。
    • 规避:在释放结构体指针后,立即将指针置为 NULL。例如,free(ptr); ptr = NULL;