MST
星途 面试题库

面试题:C语言中嵌套结构体使用malloc动态分配内存的内存管理与优化问题

有如下嵌套结构体层次结构: ```c struct Leaf { int id; struct Leaf *next; }; struct Branch { struct Leaf *leaves; struct Branch *subBranch; }; struct Tree { struct Branch *root; }; ``` 编写代码实现:1. 使用`malloc`为`struct Tree`类型的变量分配内存,并构建一个简单的树形结构,`root`下有两个`subBranch`,每个`subBranch`下有三个`Leaf`节点,`Leaf`节点的`id`依次递增。2. 编写一个函数,用于计算整棵树中所有`Leaf`节点`id`的总和。3. 编写一个函数,用于释放整棵树占用的所有内存。在实现过程中,请考虑如何优化内存分配和释放,以避免内存碎片化和泄漏问题。
46.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试
#include <stdio.h>
#include <stdlib.h>

// 定义结构体
struct Leaf {
    int id;
    struct Leaf *next;
};

struct Branch {
    struct Leaf *leaves;
    struct Branch *subBranch;
};

struct Tree {
    struct Branch *root;
};

// 构建树形结构
struct Tree* createTree() {
    struct Tree *tree = (struct Tree*)malloc(sizeof(struct Tree));
    if (!tree) return NULL;
    tree->root = (struct Branch*)malloc(sizeof(struct Branch));
    if (!tree->root) {
        free(tree);
        return NULL;
    }
    tree->root->subBranch = (struct Branch*)malloc(2 * sizeof(struct Branch));
    if (!tree->root->subBranch) {
        free(tree->root);
        free(tree);
        return NULL;
    }

    int id = 1;
    for (int i = 0; i < 2; ++i) {
        tree->root->subBranch[i].leaves = (struct Leaf*)malloc(3 * sizeof(struct Leaf));
        if (!tree->root->subBranch[i].leaves) {
            // 释放之前分配的内存
            for (int j = 0; j < i; ++j) {
                free(tree->root->subBranch[j].leaves);
            }
            free(tree->root->subBranch);
            free(tree->root);
            free(tree);
            return NULL;
        }
        for (int j = 0; j < 3; ++j) {
            tree->root->subBranch[i].leaves[j].id = id++;
            tree->root->subBranch[i].leaves[j].next = (j == 2)? NULL : &tree->root->subBranch[i].leaves[j + 1];
        }
        tree->root->subBranch[i].subBranch = NULL;
    }

    return tree;
}

// 计算所有Leaf节点id的总和
int sumLeafIds(struct Tree *tree) {
    int sum = 0;
    struct Branch *currentBranch = tree->root->subBranch;
    for (int i = 0; i < 2; ++i) {
        struct Leaf *currentLeaf = currentBranch[i].leaves;
        while (currentLeaf) {
            sum += currentLeaf->id;
            currentLeaf = currentLeaf->next;
        }
    }
    return sum;
}

// 释放整棵树占用的内存
void freeTree(struct Tree *tree) {
    struct Branch *currentBranch = tree->root->subBranch;
    for (int i = 0; i < 2; ++i) {
        struct Leaf *currentLeaf = currentBranch[i].leaves;
        struct Leaf *nextLeaf;
        while (currentLeaf) {
            nextLeaf = currentLeaf->next;
            free(currentLeaf);
            currentLeaf = nextLeaf;
        }
    }
    free(tree->root->subBranch);
    free(tree->root);
    free(tree);
}

int main() {
    struct Tree *tree = createTree();
    if (tree) {
        printf("Sum of Leaf IDs: %d\n", sumLeafIds(tree));
        freeTree(tree);
    }
    return 0;
}

说明

  1. 构建树形结构
    • 使用malloc依次为Treeroot、两个subBranch和六个Leaf节点分配内存。在分配过程中,若任何一步失败,都要释放之前分配的内存以避免内存泄漏。
    • 为每个Leaf节点的id依次赋值并设置next指针。
  2. 计算总和
    • 遍历每个subBranch下的Leaf节点链表,累加id值。
  3. 释放内存
    • 先释放每个subBranch下的Leaf节点链表,再释放subBranch数组,最后释放rootTree。这样可以有效避免内存碎片化和泄漏问题。