阵列访问期间的分段错误

时间:2017-10-26 09:49:27

标签: c++ segmentation-fault

我想从[1,10]中多次绘制1个整数,然后检查每个整数出现的次数。我写了这段代码,它正在编译但显示分段错误。请问,请指出问题出在哪里?

#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;
        }
}

4 个答案:

答案 0 :(得分:4)

如果你定义一个由10个元素组成的数组,就像你在这里一样:

std::array<int,10> count{0};

然后数组将具有索引0-9。因此count的范围是count[0]count[9]

但是,这里:

count[rand]++;

rand为10时,您正在尝试访问不存在的count [10]

要在您的修改中回答后续问题,您需要循环并创建10000随机数,此处:

 for(int i=0;i<10000;++i)
 {
     int rand=di(dre);

当您在10个不同的数字之间拣选时,您希望每个数字的数量大约为1000,并且分布均匀。

但是,当您打印结果时,将每个计数除以10000:

count[foo]/=10000;

因此,这意味着每个计数现在大约为0.1。当你将它存储在一个int中时,它会向下舍入为零。

答案 1 :(得分:2)

您的统一分布应定义为:

std::uniform_int_distribution <int> di(0, 9);

因为您的数组元素已从0索引到9。原样,您的rand变量最终将变得大于9,此时您正在读取界限,从而导致undefined behavior。即使rand保持在边界内,基于for循环的范围也将显示UB,因为foo存在实际数组元素的值,但仍用作索引。应该通过引用传递:

for (int& foo : count) {
    foo /= 10000;
    std::cout << foo << '\n';
}

此外,如果您使用的是C ++ 11,那么您需要在std::array初始化程序中使用双括号:

std::array<int, 10> count{ { 0 } };

答案 2 :(得分:2)

你调用count[rand],其中count有10个项目,意味着索引在0..9范围内,但是rand在1..10范围内,所以每隔一段时间它会调用{{1}这导致你的seg错误。

使分发使用[0..9]代替:count[10]

答案 3 :(得分:2)

使用 oExcel = CreateObject("Excel.Application") oBook = oExcel.Workbooks.Add oSheet = oBook.Worksheets(1) oSheet.Range("B1").Value = "Test" array1(i, 1) = 0 oSheet.Range("B1").NumberFormat = "0.00" oSheet.Range("A2").Resize(i, 1).Value = array1 oBook.SaveAs("C:\New folder\excel\" & datenw & ".xlsx") oBook.Close(True) oExcel.Quit() for (int foo: count)依次等于foo中的每个元素。您需要在循环中使用count而不是foo,或者如果需要索引,则使用显式count[foo]循环。

此外,for是包含边界的,因此您需要使用std::uniform_int_distribution而不是0, 9对其进行初始化,以索引您的十个元素1, 10