C++ AddressSanitizer 堆缓冲区溢出错误解析及解决方法

在 C++ 开发中,堆缓冲区溢出是一种常见的内存错误,会导致程序崩溃或产生不可预测的行为。AddressSanitizer (ASan) 是一种强大的内存错误检测工具,可以帮助开发者快速定位和解决这类问题。

本文将介绍一个典型的 AddressSanitizer 堆缓冲区溢出错误,并结合代码示例解释错误原因和解决方法。

错误信息示例

==20==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000070 at pc 0x000000367f56 bp 0x7ffc92187b90 sp 0x7ffc92187b88READ of size 8 at 0x607000000070 thread T0 #2 0x7f0dc0e00082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)0x607000000070 is located 8 bytes to the right of 72-byte region [0x607000000020,0x607000000068)allocated by thread T0 here: #5 0x7f0dc0e00082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)...

错误分析

上述错误信息表明在地址 0x607000000070 处发生了堆缓冲区溢出,程序尝试读取超过了分配内存区域的大小。

代码示例

问题出现在以下代码片段中:cppvector<vector<my_type>> buckets[bucketsize*bucketnum];

该代码声明了一个名为 buckets 的数组,数组元素类型为 vector<vector<my_type>>。问题在于,这里使用了数组来存储不定数量的桶,而数组的大小在编译时就固定了,无法动态调整。当桶的数量超过数组大小限制时,就会导致堆缓冲区溢出。

解决方法

为了解决这个问题,我们可以使用 std::vector 来存储桶,因为 std::vector 可以根据需要动态调整大小。

修改后的代码如下:cppvector<vector<my_type>> buckets(bucketnum, vector<my_type>());

这里使用 std::vector 的构造函数创建了一个包含 bucketnum 个元素的向量,每个元素都是一个空的 vector<my_type>

完整代码cppclass Solution {private: struct my_type { long value; int index; };public: bool containsNearbyAlmostDuplicate(vector& nums, int k, int t) { int i = 0, j = 1, minnum = nums[0], maxnum = nums[0], bucketsize, bucketnum, tmp; for (i = 1; i < nums.size(); i++) { minnum = min(minnum, nums[i]); maxnum = max(maxnum, nums[i]); } bucketsize = t + 1; bucketnum = (maxnum - minnum) / bucketsize + 1; vector<vector<my_type>> buckets(bucketnum, vector<my_type>()); // 修改后的代码 for (i = 0; i < nums.size(); i++) { tmp = (nums[i] - minnum) / bucketsize; if (buckets[tmp].size() != 0) { if (i - buckets[tmp].back().index <= k) return true; } if (buckets[tmp + 1].size() != 0) { if (i - buckets[tmp + 1].back().index <= k && abs(nums[i] - buckets[tmp].back().value) <= t) return true; } buckets[tmp].push_back({ nums[i], i }); } return false; }};

通过使用 std::vector 代替数组来存储桶,我们成功地解决了堆缓冲区溢出问题,并确保了代码的正确性和安全性。

希望本文能帮助您理解和解决 C++ 中的 AddressSanitizer 堆缓冲区溢出错误。


原文地址: https://www.cveoy.top/t/topic/XfK 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录