C++ AddressSanitizer 堆缓冲区溢出错误解析与解决

在进行 C++ 代码开发过程中,我们经常会遇到各种各样的错误。其中,堆缓冲区溢出 (heap-buffer-overflow) 错误是比较常见且难以调试的一类错误。本文将结合一个具体的错误案例,详细解析 AddressSanitizer 工具检测到的堆缓冲区溢出错误,并提供相应的代码修改建议。

错误信息解读

以下是案例中出现的错误信息:

==20==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000070 at pc 0x00000036812b bp 0x7ffd12f18510 sp 0x7ffd12f18508READ of size 8 at 0x607000000070 thread T0 #2 0x7efd294d2082 (/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 0x7efd294d2082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)// ... 省略部分信息 ...

这段错误信息告诉我们:

  • 错误类型: 堆缓冲区溢出 (heap-buffer-overflow)* 发生位置: 地址 0x607000000070 * 错误原因: 在地址 0x607000000070 处进行了大小为 8 字节的读取操作,但该地址超出了已分配的 72 字节内存区域。* 内存分配位置: 该内存区域由线程 T0 在代码的某个位置分配。

代码问题分析

根据错误信息,我们需要检查代码中所有访问地址 0x607000000070 附近内存的操作,特别是那些可能导致越界访问的操作。通常情况下,堆缓冲区溢出错误是由于以下原因导致的:

  • 数组越界访问: 访问数组时,索引超出了数组的边界。* 指针操作错误: 使用未初始化或指向已释放内存的指针进行读写操作。* 内存分配不足: 为数据结构分配的内存空间不足以存储所有数据。

解决案例中的错误

案例中错误的根源在于 buckets[tmp].push_back({ nums[i], i }); 这行代码。该代码尝试将元素插入到 buckets[tmp] 的向量中,但 buckets 被声明为数组而不是向量,导致 push_back 操作引发错误。

解决方案:

buckets 声明为 vector<vector<my_type>>,并使用 resize() 函数为每个桶分配空间。然后,使用 push_back() 将元素插入到相应的桶中。

**修改后的代码:**cppclass Solution {private: struct my_type { long value; int index; };public: bool containsNearbyAlmostDuplicate(vector& nums, int k, int t) { // ... 省略部分代码 ...

    vector<vector<my_type>> buckets(bucketnum); // 将 buckets 声明为向量        for (i = 0; i < nums.size(); i++) {            // ... 省略部分代码 ...

        buckets[tmp].push_back({ nums[i], i });

        // ... 省略部分代码 ...        }        return false;    }};

总结

堆缓冲区溢出错误是 C++ 开发中常见且危险的错误。通过 AddressSanitizer 等工具的帮助,我们可以更有效地定位和解决这类错误。在编写代码时,我们应该时刻注意内存管理,避免数组越界、指针错误等问题,以保证代码的健壮性和安全性


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

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