MST

星途 面试题库

面试题:C语言实现类似memcpy()和memmove()功能的优化

假设不使用标准库中的memcpy()和memmove()函数,要求你自己实现两个类似功能的函数my_memcpy()和my_memmove()。请考虑各种边界情况,如内存重叠、对齐问题等,并对实现的函数进行性能优化,最后说明优化的思路和方法。
14.0万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

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

// 自定义my_memcpy函数
void* my_memcpy(void* dest, const void* src, size_t n) {
    char* d = (char*)dest;
    const char* s = (const char*)src;
    while (n--) {
        *d++ = *s++;
    }
    return dest;
}

// 自定义my_memmove函数,处理内存重叠情况
void* my_memmove(void* dest, const void* src, size_t n) {
    char* d = (char*)dest;
    const char* s = (const char*)src;
    if (d < s) {
        while (n--) {
            *d++ = *s++;
        }
    } else {
        d += n - 1;
        s += n - 1;
        while (n--) {
            *d-- = *s--;
        }
    }
    return dest;
}

性能优化思路和方法:

  1. 使用指针运算:通过指针的直接运算,而不是数组下标访问,提高访问速度。例如 *d++ = *s++; 相比于数组访问方式效率更高。
  2. 减少循环次数:可以考虑按字长(例如4字节或8字节)进行复制,而不是每次只复制1个字节。这样可以减少循环次数,例如:
void* my_memcpy_opt(void* dest, const void* src, size_t n) {
    size_t aligned_n = n & ~3; // 按4字节对齐
    size_t remainder = n & 3;
    unsigned int* d = (unsigned int*)dest;
    const unsigned int* s = (const unsigned int*)src;
    while (aligned_n) {
        *d++ = *s++;
        aligned_n -= 4;
    }
    char* c_d = (char*)d;
    const char* c_s = (const char*)s;
    while (remainder) {
        *c_d++ = *c_s++;
        remainder--;
    }
    return dest;
}
  1. 利用CPU特性:一些CPU支持SIMD指令集(如SSE、AVX等),可以使用这些指令集一次处理多个数据,大幅提升性能。但这种方法更复杂,并且依赖于编译器和硬件平台。

注意事项:

  1. 内存对齐:在优化版本中,对数据进行按字长对齐处理,减少了多余的字节操作,提高效率。但需要注意源和目标内存地址的对齐情况,如果地址本身未对齐,直接按字长操作可能导致未定义行为。
  2. 内存重叠my_memmove 函数通过判断目标地址和源地址的位置关系,选择正向或反向复制,避免内存重叠带来的数据错误。