MST

星途 面试题库

面试题:C语言结构体数组复杂内存场景下的管理

考虑一个复杂场景,有一个结构体struct node { struct node *next; struct data { char info[100]; int value; } inner_data; }; 现在需要创建一个结构体数组,数组大小根据用户输入动态确定。每个数组元素中的next指针要构建成一个单向链表,且链表中每个节点的inner_data部分也要正确分配内存。编写代码实现这个功能,并详细阐述在内存管理过程中如何确保不发生内存泄漏,以及当链表中某个节点需要删除时,如何正确释放相关内存。
26.2万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

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

// 定义结构体
struct data {
    char info[100];
    int value;
};

struct node {
    struct node *next;
    struct data inner_data;
};

// 创建链表节点
struct node* createNode(const char* info, int value) {
    struct node* newNode = (struct node*)malloc(sizeof(struct node));
    if (newNode == NULL) {
        perror("malloc");
        return NULL;
    }
    strcpy(newNode->inner_data.info, info);
    newNode->inner_data.value = value;
    newNode->next = NULL;
    return newNode;
}

// 创建结构体数组并构建链表
struct node** createNodeArray(int size) {
    struct node** array = (struct node**)malloc(size * sizeof(struct node*));
    if (array == NULL) {
        perror("malloc");
        return NULL;
    }

    for (int i = 0; i < size; i++) {
        char info[100];
        int value;
        printf("请输入第 %d 个节点的info: ", i + 1);
        scanf("%s", info);
        printf("请输入第 %d 个节点的value: ", i + 1);
        scanf("%d", &value);

        array[i] = createNode(info, value);
        if (i > 0) {
            array[i - 1]->next = array[i];
        }
    }

    return array;
}

// 删除链表中某个节点并释放内存
void deleteNode(struct node** headRef, struct node* toDelete) {
    if (*headRef == toDelete) {
        *headRef = toDelete->next;
        free(toDelete);
        return;
    }

    struct node* current = *headRef;
    while (current != NULL && current->next != toDelete) {
        current = current->next;
    }

    if (current != NULL) {
        current->next = toDelete->next;
        free(toDelete);
    }
}

// 释放整个链表的内存
void freeList(struct node* head) {
    struct node* current = head;
    struct node* next;

    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
}

// 释放结构体数组的内存
void freeNodeArray(struct node** array, int size) {
    for (int i = 0; i < size; i++) {
        freeList(array[i]);
    }
    free(array);
}

int main() {
    int size;
    printf("请输入数组大小: ");
    scanf("%d", &size);

    struct node** array = createNodeArray(size);

    // 假设删除第二个节点
    if (size > 1) {
        deleteNode(&array[0], array[1]);
    }

    freeNodeArray(array, size);

    return 0;
}

内存管理说明

  1. 确保不发生内存泄漏

    • 在创建每个节点时,使用malloc分配内存,并在使用完后使用free释放内存。
    • 对于结构体数组,使用malloc分配数组内存,在不再使用时使用free释放。
    • 在删除链表节点时,确保找到该节点的前驱节点,调整指针并释放该节点的内存。
  2. 删除节点时正确释放内存

    • 找到要删除节点的前驱节点。
    • 调整前驱节点的next指针,跳过要删除的节点。
    • 使用free释放要删除节点的内存。
    • 在删除整个链表时,遍历链表并逐个释放每个节点的内存。