最近写代码遇到了一个隐藏很深的指针越界带来的错误,分享一下。出错部分代码如下所示:
// add handshake to the send buffer
const int string_len = sizeof(PROTOCOL_STRING) - 1;
char handshake[1 + string_len + 8 + 20 + 20];
char *ptr = handshake;
// length of version string
handshake[0] = string_len;
ptr += 1;
// protocol identifier
memcpy(ptr, &PROTOCOL_STRING, string_len);
ptr += string_len;
// 8 zeroes, reserved bits
//char reserve[8] = { 0 };
//memcpy(ptr, reserve, 8);
memset(ptr, 0, 8);
ptr += 8;
// info hash
char out[20];
to_hex(reinterpret_cast<char const*>(&infoHash[0]), sha1_hash::size, out);
memcpy(ptr, out, 20);
ptr += 20;
代码的主要BUG表现在于有时候会在最后Info hash的拷贝这里提示无法访问的内存单元,即常见的指针越界问题。而将上面的memset(ptr, 0, 8)
改为注释掉的两行之后又可以正常运行,十分的奇怪。经过仔细的检查,后来发现问题在于调用的函数to_hex()没有做长度的异常处理,该函数会修改由out开始的连续40个字节。而一开始申明的handshake和ptr地址仅仅相差了C,因而导致了该问题的出现。之所以注释掉的两行代码可以正常运行,是因为申明了新的reserve字符串数组,因而out不会修改到ptr。
正确的做法是将out改为out[40],即可完美解决问题。
总结:写、使用关于字符串、指针的处理函数时一定要注意越界问题,尽量避免使用这种不安全的函数。
欢迎关注本人公众号,公众号会更新一些不一样的内容,相信一定会有所收获。