c++ - 访问随机 vector 元素时发生访问冲突

标签 c++

我有一个整数 vector ,想随机访问它的一个元素。这是一个最小的例子:

#include <iostream>
#include <random>
#include <vector>

class Random
{
private:
    const int N = 8;
    std::vector<int> data;
    std::mt19937 randomGenerator;

public:
    void Reset(int seed = 0) {
        data.resize(N + 1);
        if(seed) { this->randomGenerator.seed(seed); }
    }

    void UpdateVector(int delta) {
        std::uniform_int_distribution<int> uniformBuffer(1, N);
        /*unsigned*/ int randomIndex = uniformBuffer( randomGenerator );
        data[randomIndex] += delta;
    }
};

int main() {
    Random rnd;
    rnd.Reset();
    rnd.UpdateVector(1);
    return 0;
}

这在 Microsoft Visual C++ 2017 的 Debug模式下完美运行。但是当我在 Release模式下运行该程序时,它因访问冲突而崩溃。快速查看生成的汇编代码会发现一些神奇的事情发生了,其中 int 索引被扩展(带符号)到 size_t,然后是一个奇怪的值(我认为添加了 0xffff0004) - 这确实不再是有效索引了!

我设法通过取消注释 randomIndex 声明中的 'unsigned' 修饰符来修复这个错误,但我很好奇为什么。这是我正在使用的编译器中的错误(快速搜索没有发现任何合理的东西)还是我有误解?

最佳答案

在调查您之前的 question昨天,它已关闭,您在将其重新发布到此处之前将其删除,问题是 Microsoft 64 位代码优化器的错误。

uniform_int_distribution<int> 中获取结果时并将其作为 size_t 传递 vector 的值 operator[] ,内部用于“将有符号范围转换为无符号范围,反之亦然”的调整因子保留在分布类之外,并针对数组访问进行缩放,从而导致问题。奇怪的是,将结果转换为 size_t 时不会发生这种情况。用于展示。

这个示例演示了这个问题。

#include <vector>
#include <random>
#include <iostream>
#include <iomanip>

const int N = 8;
std::mt19937 randomGenerator;

class tester {
public:
    int operator[](size_t idx) const {
        std::cout << "Offset is " << std::hex << idx << "\n";
        return int(idx);
    }
};

int main() {
    std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8};
    std::uniform_int_distribution<int> uniformBuffer(1, N);
    std::cout << "Number " << size_t(uniformBuffer(randomGenerator)) << "\n";
    tester t;
    std::cout << "Index " << v[t[uniformBuffer(randomGenerator)]] << "\n";
}

使用 64 位编译器,使用 cl /W4 /MD /EHsc /Ox 编译输出是

Number 5
Offset is ffffffff00000007
Index 7

v的使用是必要的。如果省略,则传递给 tester 的偏移量是 7.

关于c++ - 访问随机 vector 元素时发生访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49266674/

相关文章:

c++ - QT - 如何从 QString 中获取字符?

c++ - 使用更少的参数调用 C++ 宏

c++ - 为什么在非指针堆栈分配变量上调用 delete 时 C++ 不给出编译器错误?

c++ - vector 指针内存分配 vector

c++ - 使用谷歌分析跟踪 C++ 应用程序

c++编译后出现错误

c++ - 计算机内存中发生了什么?

C++:通过引用传递或使用私有(private)实例变量

c++ - .h(头文件)和 .cpp 文件有什么区别?

c++ - 搜索时 vector 键丢失