MST

星途 面试题库

面试题:C语言结构体变量声明的复杂场景考察

在一个大型项目中,存在结构体嵌套结构体,结构体指针指向结构体数组等复杂情况。结构体`Base`包含`int`类型成员`base_id`和`char`类型成员`base_flag`。结构体`Derived`继承自`Base`(通过包含`Base`结构体实现类似继承),并额外包含一个结构体指针数组`sub_ptr[10]`,每个指针指向一个包含`float`类型数据的结构体`Sub`。请详细说明在这种复杂结构下,声明`Derived`类型变量时,从内存管理、作用域、初始化等方面需要注意的要点,并给出完整的代码示例及解释。
50.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

内存管理要点

  1. Sub结构体数组内存分配:由于Derived中的sub_ptr是一个指针数组,需要为每个指针分配内存来指向Sub结构体实例。这通常通过mallocnew来完成。同时,使用完毕后,要记得释放这些内存,避免内存泄漏。
  2. 内存释放顺序:在释放Derived实例相关内存时,需要先释放sub_ptr数组中每个指针指向的内存,然后再释放sub_ptr数组本身(如果是动态分配的)。

作用域要点

  1. 变量作用域Derived类型变量的作用域取决于其声明位置。如果在函数内部声明,其作用域仅限于该函数块;如果在全局声明,作用域为整个程序(但要注意全局变量的使用可能带来的问题,如命名冲突等)。
  2. 结构体成员作用域Base结构体的成员(base_idbase_flag)以及Derived结构体特有的成员(sub_ptr)在Derived实例的作用域内均可访问。

初始化要点

  1. Base部分初始化:对于Base结构体部分,要在初始化Derived实例时,正确初始化base_idbase_flag
  2. sub_ptr初始化:需要为sub_ptr数组中的每个指针分配内存,并初始化所指向的Sub结构体实例。

代码示例及解释

#include <stdio.h>
#include <stdlib.h>

// 定义Sub结构体
typedef struct {
    float data;
} Sub;

// 定义Base结构体
typedef struct {
    int base_id;
    char base_flag;
} Base;

// 定义Derived结构体
typedef struct {
    Base base;
    Sub* sub_ptr[10];
} Derived;

// 初始化Derived实例
Derived* createDerived(int id, char flag) {
    Derived* derived = (Derived*)malloc(sizeof(Derived));
    if (derived == NULL) {
        return NULL;
    }
    derived->base.base_id = id;
    derived->base.base_flag = flag;
    for (int i = 0; i < 10; i++) {
        derived->sub_ptr[i] = (Sub*)malloc(sizeof(Sub));
        if (derived->sub_ptr[i] == NULL) {
            // 如果分配失败,释放之前已分配的内存
            for (int j = 0; j < i; j++) {
                free(derived->sub_ptr[j]);
            }
            free(derived);
            return NULL;
        }
        derived->sub_ptr[i]->data = (float)i;
    }
    return derived;
}

// 释放Derived实例的内存
void freeDerived(Derived* derived) {
    if (derived != NULL) {
        for (int i = 0; i < 10; i++) {
            if (derived->sub_ptr[i] != NULL) {
                free(derived->sub_ptr[i]);
            }
        }
        free(derived);
    }
}

int main() {
    Derived* myDerived = createDerived(1, 'A');
    if (myDerived != NULL) {
        printf("Base id: %d, Base flag: %c\n", myDerived->base.base_id, myDerived->base.base_flag);
        for (int i = 0; i < 10; i++) {
            printf("Sub data at index %d: %f\n", i, myDerived->sub_ptr[i]->data);
        }
        freeDerived(myDerived);
    }
    return 0;
}
  1. Sub结构体:定义了包含float类型数据的Sub结构体。
  2. Base结构体:定义了包含int类型base_idchar类型base_flagBase结构体。
  3. Derived结构体:通过包含Base结构体实现类似继承,并包含一个Sub结构体指针数组sub_ptr
  4. createDerived函数:用于初始化Derived实例。首先为Derived实例分配内存,然后初始化Base部分的成员。接着为sub_ptr数组中的每个指针分配内存,并初始化所指向的Sub结构体实例。
  5. freeDerived函数:用于释放Derived实例相关的内存。先释放sub_ptr数组中每个指针指向的内存,再释放Derived实例本身的内存。
  6. main函数:创建一个Derived实例,输出其成员值,然后释放内存。