携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情。
总览C++算法开发的一些注意事项,常见的算法题。
一、C语言陷阱
1. 一道入门题:Memmov,把内存中的一块内容从 src 处拷贝到 des 处,拷贝的长度是 n
void *memmove(void *dest, const void *src, size_t n) {
// implementation here
}
其中
- dest -- 指向用于存储复制内容的目标数组,类型强制转换为 void* 指针。
- src -- 指向要复制的数据源,类型强制转换为 void* 指针。
- n -- 要被复制的字节数。
(1)错误事例
void *memmove(void *dest, const void *src, size_t n)
{
char *p1 = dest;
char *p2 = src;
while (*p2 != \0)
*p1++ = *p2++;
return p1;
}
(2)C语⾔的陷阱
- 内存重叠的处理
【情况1】内存重叠,造成拷贝后原数据丢失,最终dest值为 1212
【情况2】非内存重叠,破坏原始数据
- 临时变量太多或者没安全释放
- 没有测试内存越界
- 指针操作不熟悉
(3)正确解法
void* my_memmove(void *dest, const void *src, int n)
{
assert(dest != NULL);
assert(src != NULL);
char *p_dest = (char*)dest;
const char *p_src = (char*)src;
if (p_src < p_dest)
{
//dest: x x o o o o o o
//src: o o o o o o
//内存重叠,从后往前拷贝
p_src += n;
p_dest += n;
while (n-- != 0)
{
*(--p_dest) = *(--p_src);
}
}
else
{
//【情况1:起始位置相同,无需拷贝】
//dest: o o o o o o
//src: o o o o o o
//【情况2:源在后,正向拷贝】
//dest: o o o o o o
//src: x x o o o o o o
//正向赋值
while (n-- != 0)
{
*(char*)p_dest++ = *(char*)p_src++;
}
}
return dest;
}
测试
int main()
{
char dest[] = "00123456789";
std::cout << "After memmove dest:" << (char*)my_memmove(dest, dest+2, 4);
//std::cout << "After memmove dest:" << (char*)my_memmove(dest+2, dest, 4);
return 0;
}
上述代码给出了防止数组越界的测试 测试数据: dest:00123456789 src: xx123456789 二者地址的关系是: dest < src (如下图所示)
根据注释的内容可以尝试,dest > src 的情况的测试。
可以思考一下代码是不是还有其他问题呢?