In the file src/random.h:
template <typename I, typename R>
void Shuffle(I first, I last, R&& rng)
{
while (first != last) {
size_t j = rng.randrange(last - first);
if (j) {
using std::swap;
swap(*first, *(first + j));
}
++first;
}
}
The argument rng is an instance of the FastRandomContext class. The member function randrange defined as follows:
uint64_t randrange(uint64_t range) noexcept
{
assert(range);
--range;
int bits = CountBits(range);
while (true) {
uint64_t ret = randbits(bits);
if (ret <= range) return ret;
}
}
it returns value <= range。 means that the swap(*first, *(first + j)); the j variable may be equal to vector size. so *(first + j) may be overflow. As a result, the value of an item in the vector may be empty after Shuffle。
Expected behavior
Causes some values to be empty after Shuffle.
Actual behavior
To reproduce
System information
the latest version
In the file src/random.h:
template <typename I, typename R>
void Shuffle(I first, I last, R&& rng)
{
while (first != last) {
size_t j = rng.randrange(last - first);
if (j) {
using std::swap;
swap(*first, *(first + j));
}
++first;
}
}
The argument rng is an instance of the FastRandomContext class. The member function randrange defined as follows:
uint64_t randrange(uint64_t range) noexcept
{
assert(range);
--range;
int bits = CountBits(range);
while (true) {
uint64_t ret = randbits(bits);
if (ret <= range) return ret;
}
}
it returns value <= range。 means that the swap(*first, *(first + j)); the j variable may be equal to vector size. so *(first + j) may be overflow. As a result, the value of an item in the vector may be empty after Shuffle。
Expected behavior
Causes some values to be empty after Shuffle.
Actual behavior
To reproduce
System information
the latest version