Reputation: 795
I want to draw 1 integer from [1,10] a large number of times, then check how many times each integer appears. I wrote this code, it is compiling but showing segmentation fault. Can you, please, point out where the problem is?
#include <iostream>
#include <random>
#include <array>
int main(){
std::random_device rd;
std::mt19937 dre(rd());
std::uniform_int_distribution <int> di(1,10);
std::array<int,10> count{0};
for(int i=0;i<10000;++i)
{
int rand=di(dre);
count[rand]++;
}
for (int foo: count){
count[foo]/=10000;
std::cout << foo << " " << count[foo] << std::endl;
}
}
Upvotes: 0
Views: 1851
Reputation: 1757
If you define an array consisting of 10 elements, like you do here:
std::array<int,10> count{0};
Then the array will have indices 0-9. So count
will range from count[0]
to count[9]
.
However, here:
count[rand]++;
when rand
is 10, you're trying to access count [10]
, which doesn't exist.
To answer the followup question in your edit, you're looping round and creating 10000
random numbers, here:
for(int i=0;i<10000;++i)
{
int rand=di(dre);
And as you're picking between 10 different numbers, you'd expect the count of each one to be approximately 1000, with a uniform distribution.
However, when you come to print the results, you divide each count by 10000:
count[foo]/=10000;
So this means it's highly likely that each count is now approx 0.1. As you're storing it in an int, this gets rounded down to zero.
Upvotes: 4
Reputation: 15501
Your uniform distribution should be defined as:
std::uniform_int_distribution <int> di(0, 9);
because your array elements are indexed from 0
to 9
. As-is your rand
variable will eventually become greater than 9
at which point you are reading out of bounds thus causing undefined behavior. Even if rand
stays within boundaries your range based for
loop will exhibit UB because foo
there is the value of the actual array element yet used as an index. Should be passed by reference instead:
for (int& foo : count) {
foo /= 10000;
std::cout << foo << '\n';
}
Also if you are using C++11 then you will need double braces for the std::array initializer here:
std::array<int, 10> count{ { 0 } };
Upvotes: 2
Reputation: 63124
With for (int foo: count)
, foo
is equal to each element in count
in turn. You need to use foo
on its own in the loop instead of count[foo]
, or use an explicit for
loop if you need the index.
Additionally, std::uniform_int_distribution
is bounds-inclusive, so you need to initialize it with 0, 9
instead of 1, 10
to index into your ten-elements count
.
Upvotes: 2
Reputation: 5582
You call count[rand]
where count has 10 items, meaning indices in the range of 0..9 but rand is in the range of 1..10 so every once in a while it will call count[10]
which causes your seg fault.
Make the distribution use [0..9] instead: std::uniform_int_distribution <int> di(0,9);
Upvotes: 2