Yak*_*kov 3 c algorithm buffer memcpy
我发现了memcpy的以下实现(面试问题,其中迭代计数~size/4):
void memcpy(void* dest, void* src, int size)
{
uint8_t *pdest = (uint8_t*) dest;
uint8_t *psrc = (uint8_t*) src;
int loops = (size / sizeof(uint32_t));
for(int index = 0; index < loops; ++index)
{
*((uint32_t*)pdest) = *((uint32_t*)psrc);
pdest += sizeof(uint32_t);
psrc += sizeof(uint32_t);
}
loops = (size % sizeof(uint32_t));
for (int index = 0; index < loops; ++index)
{
*pdest = *psrc;
++pdest;
++psrc;
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定我理解它.....:
1)为什么要定义uint8_t *pdest,uint8_t *psrc并在此之后进行铸造uint32_t-
*((uint32_t*)pdest) = *((uint32_t*)psrc);
Run Code Online (Sandbox Code Playgroud)
我认为,从一开始pdest,并psrc应被定义为uint32_t的......我缺少什么?2)我认为这个实现存在问题:if src = 0x100和dst = 0x104
src(原始)看起来像这样:
-------------------------
| 6 | 8 | 7 | 1 |
-------------------------
0x100 0x104 0x108 0x1C0
Run Code Online (Sandbox Code Playgroud)
在执行之后它会是那样的
-------------------------
| 6 | 6 | 6 | 6 |.....
-------------------------
0x100 0x104 0x108 0x1C0
Run Code Online (Sandbox Code Playgroud)
尽管如此,以下内存布局应该是一个结果
-------------------------
| 6 | 6 | 8 | 7 |....
-------------------------
0x100 0x104 0x108 0x1C0
Run Code Online (Sandbox Code Playgroud)
这memcpy()会遇到另一个问题:如果一个或两个缓冲区不在适当的边界上会发生什么?这可能会显着影响性能,或者在某些体系结构上,甚至无法运行代码.另一个常见问题(但不是这里)是处理缓冲区,其长度不是native(uint32)类型宽度的倍数.您的示例使用uint8类型(然后根据需要进行转换)的原因是允许复制尾随字节而不进行强制转换.如果你转换大部分传输或只是尾随字节,它没有任何区别.考虑到缓冲区对齐,您可能会提前复制初始未对齐数据,直到建立对齐为止.
memcpy()当源和目标重叠时,不保证该功能以定义的方式工作; 因此,您标记为第二个问题不是问题.如果代替memcpy(),这个代码用于实现memmove(),那么问题将是真实的.