MST

星途 面试题库

面试题:C语言嵌套结构体与动态内存分配及释放

设计一个包含嵌套结构体的链表结构,链表节点的结构体定义如下: ```c struct Data { char *str; int value; }; struct Node { struct Data data; struct Node *next; }; ``` 要求编写函数实现链表的创建(动态分配内存)、遍历以及释放(释放所有动态分配的内存,包括`str`指向的内存)。请阐述在实现过程中如何避免内存泄漏,尤其是在嵌套结构体涉及动态内存分配的情况下。
49.8万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

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

// 创建新的Data结构体
struct Data* createData(const char *str, int value) {
    struct Data *newData = (struct Data*)malloc(sizeof(struct Data));
    if (!newData) {
        perror("malloc for Data");
        return NULL;
    }
    newData->str = (char*)malloc(strlen(str) + 1);
    if (!newData->str) {
        perror("malloc for str");
        free(newData);
        return NULL;
    }
    strcpy(newData->str, str);
    newData->value = value;
    return newData;
}

// 创建新的Node结构体
struct Node* createNode(const char *str, int value) {
    struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
    if (!newNode) {
        perror("malloc for Node");
        return NULL;
    }
    newNode->data = *createData(str, value);
    newNode->next = NULL;
    return newNode;
}

// 创建链表
struct Node* createList(const char *strs[], int values[], int size) {
    if (size <= 0) return NULL;
    struct Node *head = createNode(strs[0], values[0]);
    struct Node *current = head;
    for (int i = 1; i < size; i++) {
        current->next = createNode(strs[i], values[i]);
        current = current->next;
    }
    return head;
}

// 遍历链表
void traverseList(struct Node *head) {
    struct Node *current = head;
    while (current) {
        printf("str: %s, value: %d\n", current->data.str, current->data.value);
        current = current->next;
    }
}

// 释放链表内存
void freeList(struct Node *head) {
    struct Node *current = head;
    struct Node *next;
    while (current) {
        next = current->next;
        free(current->data.str);
        free(current);
        current = next;
    }
}

在实现过程中避免内存泄漏的方法:

  1. 动态内存分配检查:每次调用malloc时,检查返回值是否为NULL。如果是NULL,表示内存分配失败,应进行相应处理(如释放已分配的内存并返回错误)。
  2. 按顺序释放内存:在释放链表节点时,先释放嵌套结构体Datastr指向的内存,再释放Data结构体本身(如果是单独分配的),最后释放Node结构体。在遍历链表释放节点时,使用临时指针记录下一个节点,防止在释放当前节点后丢失链表结构。这样可以确保所有动态分配的内存都被正确释放,避免内存泄漏。