MST

星途 面试题库

面试题:C++中struct和union嵌套使用的复杂场景及内存管理

假设你正在开发一个多媒体处理系统,需要定义一种数据结构来存储不同类型的媒体元数据。要求使用struct和union的嵌套结构来实现,其中可能包含字符串、整数、浮点数等不同类型数据,并且要考虑到内存对齐、动态内存分配与释放以及不同平台下的兼容性。请详细描述你的设计思路,并给出核心代码示例,同时分析可能出现的内存管理问题及解决方案。
40.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 使用structunion嵌套:利用union来存储不同类型的数据,struct来组织相关信息。
  2. 内存对齐:通过#pragma pack等方式控制结构体的内存对齐,以确保不同平台下兼容性。
  3. 动态内存分配与释放:对于字符串类型的数据,使用动态内存分配函数(如malloc),并在适当的时候释放(如free)。

核心代码示例

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

// 使用 #pragma pack 控制内存对齐,以4字节对齐为例
#pragma pack(4) 

// 定义存储不同类型数据的 union
union MetaDataValue {
    int intValue;
    float floatValue;
    char* stringValue;
};

// 定义存储媒体元数据的 struct
struct MediaMetaData {
    char type; // 'i' 表示 int, 'f' 表示 float,'s' 表示 string
    union MetaDataValue value;
};

// 创建元数据函数
struct MediaMetaData* createMetaData(char type) {
    struct MediaMetaData* meta = (struct MediaMetaData*)malloc(sizeof(struct MediaMetaData));
    meta->type = type;
    if (type =='s') {
        meta->value.stringValue = NULL;
    }
    return meta;
}

// 设置 int 类型元数据
void setIntMetaData(struct MediaMetaData* meta, int value) {
    if (meta->type == 'i') {
        meta->value.intValue = value;
    }
}

// 设置 float 类型元数据
void setFloatMetaData(struct MediaMetaData* meta, float value) {
    if (meta->type == 'f') {
        meta->value.floatValue = value;
    }
}

// 设置 string 类型元数据
void setStringMetaData(struct MediaMetaData* meta, const char* value) {
    if (meta->type =='s') {
        if (meta->value.stringValue!= NULL) {
            free(meta->value.stringValue);
        }
        meta->value.stringValue = (char*)malloc(strlen(value) + 1);
        strcpy(meta->value.stringValue, value);
    }
}

// 获取 int 类型元数据
int getIntMetaData(struct MediaMetaData* meta) {
    if (meta->type == 'i') {
        return meta->value.intValue;
    }
    return 0;
}

// 获取 float 类型元数据
float getFloatMetaData(struct MediaMetaData* meta) {
    if (meta->type == 'f') {
        return meta->value.floatValue;
    }
    return 0.0f;
}

// 获取 string 类型元数据
const char* getStringMetaData(struct MediaMetaData* meta) {
    if (meta->type =='s') {
        return meta->value.stringValue;
    }
    return "";
}

// 释放元数据内存
void freeMetaData(struct MediaMetaData* meta) {
    if (meta->type =='s' && meta->value.stringValue!= NULL) {
        free(meta->value.stringValue);
    }
    free(meta);
}

可能出现的内存管理问题及解决方案

  1. 内存泄漏
    • 问题:如果在设置字符串元数据时没有释放旧的字符串内存,或者在使用完MediaMetaData结构体后没有释放其占用的内存,就会导致内存泄漏。
    • 解决方案:在setStringMetaData函数中,每次重新设置字符串时先释放旧的字符串内存。在freeMetaData函数中,释放结构体占用的所有动态分配内存。
  2. 悬空指针
    • 问题:如果先释放了MediaMetaData结构体的内存,然后再访问其成员,就会出现悬空指针问题。
    • 解决方案:在释放内存后,将指向该结构体的指针设置为NULL,避免后续误访问。

取消内存对齐控制

#pragma pack()