MST

星途 面试题库

面试题:C语言结构体成员访问安全性之指针偏移问题

假设有如下结构体定义:struct { int a; char b; float c; } myStruct; 若定义一个指向该结构体类型的指针p并正确初始化,如何通过指针安全地访问结构体成员b,同时说明在这个过程中可能出现的因指针偏移导致的安全性问题及如何避免。
26.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
  1. 通过指针安全访问结构体成员b: 假设p已经正确初始化指向myStruct类型的结构体变量。可以使用->运算符来访问结构体成员。例如:
    struct { int a; char b; float c; } myStruct;
    struct { int a; char b; float c; } *p = &myStruct;
    char valueOfB = p->b;
    
  2. 指针偏移导致的安全性问题
    • 问题描述:结构体在内存中存储时,由于成员类型不同,可能存在内存对齐的情况。如果错误地进行指针偏移计算,比如直接将p当作普通char*指针进行偏移,可能会访问到错误的内存位置。例如:
    // 错误示例
    struct { int a; char b; float c; } myStruct;
    struct { int a; char b; float c; } *p = &myStruct;
    char *wrongPtr = (char*)p + sizeof(int); // 错误的偏移,没有考虑内存对齐
    char wrongValue = *wrongPtr; // 可能访问到错误的内存
    
    • 危害:这可能导致读取到无效数据,或者在写入时覆盖到不应该修改的内存区域,从而引发程序崩溃、数据损坏等问题。
  3. 避免方法
    • 使用结构体指针和->运算符来访问成员,这样编译器会根据结构体定义自动处理正确的偏移。如上述正确访问b的示例。
    • 不要手动进行指针偏移计算,除非你对结构体的内存布局和内存对齐规则有非常清楚的了解。如果确实需要手动偏移,要使用offsetof宏来获取成员在结构体中的偏移量。例如:
    #include <stddef.h>
    struct { int a; char b; float c; } myStruct;
    struct { int a; char b; float c; } *p = &myStruct;
    char *correctPtr = (char*)p + offsetof(struct { int a; char b; float c; }, b);
    char correctValue = *correctPtr;
    
    这样通过offsetof宏获取的偏移量是准确的,能避免因手动计算偏移量错误而导致的安全性问题。