MST

星途 面试题库

面试题:C语言memcpy()和memmove()在复杂数据结构中的应用

假设有一个复杂的结构体,结构体中包含数组、指针等多种数据类型。请编写代码使用memcpy()和memmove()分别对该结构体实例进行复制操作,并处理可能出现的内存重叠问题,同时分析在这种情况下使用这两个函数需要注意的要点。
29.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

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

// 定义复杂结构体
typedef struct {
    int arr[5];
    char *ptr;
    double num;
} ComplexStruct;

// 使用memcpy进行复制
ComplexStruct memcpyCopy(const ComplexStruct *src) {
    ComplexStruct dest;
    // 先复制非指针部分
    memcpy(&dest.arr, &src->arr, sizeof(src->arr));
    memcpy(&dest.num, &src->num, sizeof(src->num));
    // 分配内存并复制指针指向的内容
    dest.ptr = (char *)malloc(strlen(src->ptr) + 1);
    if (dest.ptr != NULL) {
        memcpy(dest.ptr, src->ptr, strlen(src->ptr) + 1);
    }
    return dest;
}

// 使用memmove进行复制
ComplexStruct memmoveCopy(const ComplexStruct *src) {
    ComplexStruct dest;
    // 先复制非指针部分
    memmove(&dest.arr, &src->arr, sizeof(src->arr));
    memmove(&dest.num, &src->num, sizeof(src->num));
    // 分配内存并复制指针指向的内容
    dest.ptr = (char *)malloc(strlen(src->ptr) + 1);
    if (dest.ptr != NULL) {
        memmove(dest.ptr, src->ptr, strlen(src->ptr) + 1);
    }
    return dest;
}

int main() {
    ComplexStruct original;
    original.ptr = "Hello";
    original.num = 3.14;
    for (int i = 0; i < 5; i++) {
        original.arr[i] = i;
    }

    ComplexStruct memcpyResult = memcpyCopy(&original);
    ComplexStruct memmoveResult = memmoveCopy(&original);

    // 输出验证
    printf("memcpy result:\n");
    for (int i = 0; i < 5; i++) {
        printf("arr[%d]: %d\n", i, memcpyResult.arr[i]);
    }
    printf("ptr: %s\n", memcpyResult.ptr);
    printf("num: %lf\n", memcpyResult.num);

    printf("memmove result:\n");
    for (int i = 0; i < 5; i++) {
        printf("arr[%d]: %d\n", i, memmoveResult.arr[i]);
    }
    printf("ptr: %s\n", memmoveResult.ptr);
    printf("num: %lf\n", memmoveResult.num);

    // 释放内存
    free(memcpyResult.ptr);
    free(memmoveResult.ptr);

    return 0;
}

注意要点

  1. 内存重叠memcpy并不保证在源内存区域和目标内存区域重叠时能正确工作。而memmove可以处理重叠的内存区域,它会先将源数据复制到一个临时缓冲区,然后再从临时缓冲区复制到目标区域。
  2. 指针处理:对于结构体中的指针成员,需要单独分配内存并复制指针指向的内容,不能简单地使用memcpymemmove复制指针本身,否则会导致多个指针指向同一块内存,在释放内存时容易出现问题。
  3. 内存管理:使用完复制后的结构体,如果其中包含动态分配的内存(如指针指向的内容),需要正确释放内存,避免内存泄漏。