最近写代码遇到了一个隐藏很深的指针越界带来的错误,分享一下。出错部分代码如下所示:
// 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],即可完美解决问题。
总结:写、使用关于字符串、指针的处理函数时一定要注意越界问题,尽量避免使用这种不安全的函数。
欢迎关注本人公众号,公众号会更新一些不一样的内容,相信一定会有所收获。