c++ - 这段代码会抛出访问冲突异常吗

标签 c++ templates pointers

考虑这段代码:

template <typename T>
void foo(unsigned char * tempbuf, T val, int &nMatches, int nSize)
{
    T temp_val;
    for (int offset = 0; offset < nSize; ++offset)
    {
        temp_val = *((T*)&tempbuf[offset]);
        if (temp_val == val)
        {
            ++nMatches;
        }               
    }
}
int main ()
{
    int nValue = 5;
    int nMatches(0);
    const int size = 1000;
    unsigned char *buffer = reinterpret_cast <unsigned char *>(malloc(size));
    foo(buffer, nValue, nMatches, size);
    return 1;
}

考虑到nValue是一个int,foo将读取缓冲区的第1000个字节作为一个int(例如至少32位变量)。这是否意味着可能会因未分配内存上的访问冲突而引发异常? (假设 int 是 4 个字节,最后一次读取时可能不存在 3 个字节,如果它们确实存在,它们可能具有垃圾值,所以我知道它至少是 UB,但考虑到要读取的地址本身有效,我不确定该异常)。

最佳答案

假设如下:

  • 您知道,在分配的缓冲区之外进行读取是一种糟糕的做法
  • 我们不是在讨论“如何修复代码”,而是在讨论“可能发生什么”

正如您所提到的,在 foo() 内循环的最后一次迭代中,您正在读取分配的缓冲区之外的几个字节。访问随机内存总是有可能崩溃 segmentation fault ,但在这种特殊情况下,出现不良结果的可能性微不足道,但仍然不为零。原因:

  • 缓冲区是在堆内分配的,因此缓冲区后面的字节也可能是堆的一部分(除非缓冲区位于堆边界的右侧),因此读取将返回垃圾而不会失败。
  • 即使走出堆也可能不会影响到你。几乎不可能预测,您将读取什么内存,特别是考虑到 address randomization technique 。你有可能得到好的和坏的结果(例如,地址空间边界上的堆肯定会导致读取错误)。根据 Google 的说法,通过尝试 VMMap 可以获得有关虚拟内存映射的深刻见解。实用程序,但我不是为自己做的。

所以底线是你的程序里有定时炸弹,但不清楚我们是否能活着看到爆炸。

关于c++ - 这段代码会抛出访问冲突异常吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41591566/

相关文章:

c++ - Clang 可变参数模板特化错误 : non-deducible template parameter

c++ - 继承层次结构中的特定类作为 boost::signals2 回调中的类型

c++ - 可变参数模板示例未编译

C++ lambda指针/引用内存占用之争

c - 最后一个难题是在 C 中更改此函数

c++ - 在 Vector c++ 中使用指针成员初始化对象

C++ 非抽象析构函数继承

c++在序列之前删除字符串中的所有内容,包括序列

c++ - 如何在特定时间后重新启动窗口服务

c++ - 为什么推导 F 时 std::is_function<F> 返回 false_type?