MST

星途 面试题库

面试题:C语言指针运算与内存管理

在C语言中,假设你需要实现一个简单的动态数组管理模块。首先,编写一个函数 `void* createDynamicArray(int size, int elementSize);`,该函数用于分配一块连续的内存,大小为 `size` 个 `elementSize` 字节,并返回指向这块内存的指针。然后编写一个函数 `void expandDynamicArray(void** array, int oldSize, int newSize, int elementSize);`,该函数用于扩展已有的动态数组,将其大小从 `oldSize` 扩展到 `newSize`,并保证原有的数据不丢失。在扩展过程中,可能需要重新分配内存并复制数据。最后编写一个函数 `void freeDynamicArray(void* array);`,用于释放动态数组所占用的内存。请详细说明在这些函数中指针运算的原理,包括如何通过指针运算访问和操作内存中的数据,以及在内存分配和释放过程中指针的变化情况。同时,分析在实现这些功能时可能会遇到的内存泄漏问题,并说明如何避免。
27.0万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

createDynamicArray 函数实现及指针运算原理

void* createDynamicArray(int size, int elementSize) {
    void* array = malloc(size * elementSize);
    if (array == NULL) {
        // 内存分配失败处理
        return NULL;
    }
    return array;
}
  • 指针运算原理malloc 函数分配一块连续的内存,大小为 size * elementSize 字节,并返回指向这块内存起始地址的指针。这里通过简单的乘法运算确定所需内存大小,malloc 内部实现可能涉及操作系统的内存管理机制,返回的指针直接指向分配的内存块。
  • 内存分配过程中指针的变化malloc 成功时,返回一个有效的指针指向分配的内存;失败时,返回 NULL

expandDynamicArray 函数实现及指针运算原理

void expandDynamicArray(void** array, int oldSize, int newSize, int elementSize) {
    void* newArray = realloc(*array, newSize * elementSize);
    if (newArray == NULL) {
        // 内存重新分配失败处理
        return;
    }
    *array = newArray;
}
  • 指针运算原理realloc 函数尝试重新分配内存块。如果新的大小小于或等于旧的大小,realloc 可能会在原内存块基础上进行调整;如果新的大小大于旧的大小,realloc 通常会分配一块新的更大的内存块,并将原内存块的数据复制到新的内存块中,然后释放原内存块。这里通过 *array 间接访问原动态数组的指针,新分配的内存块地址通过 realloc 返回并重新赋值给 *array
  • 内存分配和释放过程中指针的变化realloc 成功时,*array 被更新为新的内存块地址;失败时,*array 保持不变,原内存块仍然有效。

freeDynamicArray 函数实现及指针运算原理

void freeDynamicArray(void* array) {
    free(array);
}
  • 指针运算原理free 函数用于释放之前通过 mallocrealloc 分配的内存。free 函数只需要传入指向已分配内存块起始地址的指针,即可释放这块内存。
  • 内存释放过程中指针的变化free 函数释放内存后,传入的指针在逻辑上变为悬空指针(dangling pointer),虽然指针的值不变,但指向的内存已无效。建议在调用 free 后将指针赋值为 NULL,避免误操作。

可能遇到的内存泄漏问题及避免方法

  • 问题
    • createDynamicArray 中,如果 malloc 失败没有正确处理,可能导致程序继续使用 NULL 指针,引发未定义行为。
    • expandDynamicArray 中,如果 realloc 失败但没有将原指针保持有效,可能导致原内存块无法释放,从而造成内存泄漏。
    • 如果 freeDynamicArray 函数没有被正确调用,动态数组所占用的内存将不会被释放,导致内存泄漏。
  • 避免方法
    • createDynamicArrayexpandDynamicArray 中,每次内存分配(mallocrealloc)后都要检查返回值是否为 NULL,如果是则进行适当处理,如返回错误或终止程序。
    • expandDynamicArray 中,在 realloc 失败时,确保原指针保持有效,以便后续可以正确释放内存。
    • 确保在动态数组不再使用时,及时调用 freeDynamicArray 函数释放内存,并且在调用 free 后将指针置为 NULL