MST

星途 面试题库

面试题:C语言结构体在复杂数据结构设计及内存管理中的优化

假设要设计一个表示多层嵌套的树形结构的C语言结构体,节点包含不同类型的数据成员且数量不定。要求考虑内存管理的优化,避免内存碎片化。请描述结构体设计思路,并提供关键代码片段展示如何进行内存分配、释放以及节点的增删操作。
22.8万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

结构体设计思路

  1. 通用节点结构体:设计一个通用的节点结构体,包含一个指向数据的指针,这样可以通过该指针指向不同类型的数据,从而实现不同类型数据成员的支持。
  2. 动态内存分配:为了避免内存碎片化,采用大块内存分配的方式。可以预先分配一定大小的内存池,节点的数据成员从这个内存池中分配。
  3. 树形结构:在节点结构体中包含指向子节点和兄弟节点的指针,以实现多层嵌套的树形结构。

关键代码片段

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

// 定义一个通用的数据类型,用于表示不同类型的数据
typedef union {
    int int_data;
    float float_data;
    char* string_data;
    // 可以根据需要添加更多的数据类型
} Data;

// 定义节点结构体
typedef struct Node {
    Data data;
    struct Node* child;
    struct Node* sibling;
} Node;

// 内存池相关
#define MEMORY_POOL_SIZE 1024 * 1024 // 1MB内存池
static char memory_pool[MEMORY_POOL_SIZE];
static int pool_index = 0;

// 从内存池分配内存
void* allocate_from_pool(size_t size) {
    if (pool_index + size > MEMORY_POOL_SIZE) {
        fprintf(stderr, "内存池不足\n");
        return NULL;
    }
    void* ptr = &memory_pool[pool_index];
    pool_index += size;
    return ptr;
}

// 创建新节点
Node* create_node() {
    Node* new_node = (Node*)allocate_from_pool(sizeof(Node));
    if (!new_node) return NULL;
    new_node->child = NULL;
    new_node->sibling = NULL;
    return new_node;
}

// 设置节点数据(以设置int类型数据为例)
void set_node_data_int(Node* node, int value) {
    node->data.int_data = value;
}

// 添加子节点
void add_child(Node* parent, Node* child) {
    if (parent->child) {
        Node* sibling = parent->child;
        while (sibling->sibling) {
            sibling = sibling->sibling;
        }
        sibling->sibling = child;
    } else {
        parent->child = child;
    }
}

// 删除子节点(以删除第一个子节点为例)
void remove_child(Node* parent) {
    if (parent->child) {
        Node* temp = parent->child;
        parent->child = parent->child->sibling;
        // 这里没有真正释放子节点占用的内存,实际应用中可能需要递归释放子节点及其所有后代节点
    }
}

// 释放内存池(简单示例,实际可能需要更复杂的处理)
void free_memory_pool() {
    pool_index = 0;
}

代码说明

  1. 通用数据类型:通过union定义了一个通用的数据类型Data,可以存储不同类型的数据。
  2. 节点结构体Node结构体包含Data类型的数据成员以及指向子节点和兄弟节点的指针。
  3. 内存池分配allocate_from_pool函数从预先定义的内存池中分配内存,避免了频繁的小块内存分配导致的碎片化。
  4. 节点操作create_node函数创建新节点,set_node_data_int设置节点的int类型数据,add_child添加子节点,remove_child删除子节点(简单示例,实际可能需要更复杂的递归删除)。
  5. 内存池释放free_memory_pool函数简单重置内存池索引,实际应用中可能需要更复杂的内存清理操作。