在C程序中,我随机增加数组中的一些整数元素。未添加的值无论如何都会更改。为什么?

在C程序中,我随机增加数组中的一些整数元素。未添加的值无论如何都会更改。为什么?,c,arrays,random,C,Arrays,Random,我有一个包含400个元素的整数数组。我用0初始化每个元素(甚至在之后检查它是否真的为0,因为我找不到这种行为的原因) 然后我选择10000个随机[1]索引,并将这些索引处的数组元素增加1。随机选择的索引中没有一个大于321(我确实检查过)。但是,在这10000次随机增加之后,索引为399或398的数组元素大于0。为什么? #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include &

我有一个包含400个元素的整数数组。我用0初始化每个元素(甚至在之后检查它是否真的为0,因为我找不到这种行为的原因)

然后我选择10000个随机[1]索引,并将这些索引处的数组元素增加1。随机选择的索引中没有一个大于321(我确实检查过)。但是,在这10000次随机增加之后,索引为399或398的数组元素大于0。为什么?

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stddef.h>
#include <time.h>

#define NUM_INCREASES 10000
#define RESULTS_SIZE 400
#define ONES_IDX 2
#define TENS_IDX 1
#define HUNDREDS_IDX 0

int main(int argc, char * argv[]) {
    int decimalDigits[3];
    int results[RESULTS_SIZE] = {0};

    srand(time(NULL));

    for (int i=0; i<RESULTS_SIZE; i++) {
        if (results[i]>0) {
            printf("%05d %05d \n", results[i], i);
        }
    }
    puts("---");

    for (int i=0; i<NUM_INCREASES; i++) {
        decimalDigits[0] = 0;
        decimalDigits[1] = 0;
        decimalDigits[2] = 0;
        for (int digitIncrease = 0; digitIncrease<3; digitIncrease++) {
            int digitIndex = rand()%(decimalDigits[ONES_IDX]>0 ? 2 : 3);
            if (digitIndex == TENS_IDX && decimalDigits[TENS_IDX] == 2) {
                digitIndex -= 1 + 2*(i%2);
            }

            decimalDigits[digitIndex]++;
        }
        if (decimalDigits[TENS_IDX] > 2 || decimalDigits[ONES_IDX] > 1) {
            fprintf(stderr, "error %d\n", __LINE__);
        }
        int toIncrease = decimalDigits[HUNDREDS_IDX] * 100 + decimalDigits[TENS_IDX] * 10 + decimalDigits[ONES_IDX];
        if (toIncrease < 0 || toIncrease > 321) {
            fprintf(stderr, "error %d\n", __LINE__);
        }
        results[toIncrease]++;
    }

    for (int i=0; i<RESULTS_SIZE; i++) {
        if (results[i]>0) {
            printf("%05d %05d \n", results[i], i);
        }
    }

    return EXIT_SUCCESS;
}
这里的错误是什么?399不应该在输出的第二列中

脚注:


[1] 随机索引是从数字0开始生成的。然后将该数字的一个随机小数位数增加3倍。但是,则“一”位数最多增加1次。“十”位数最多增加2倍。

当我按原样运行代码时,这一行将导致负数组索引:

for (int digitIncrease = 0; digitIncrease<3; digitIncrease++) {
    int digitIndex = rand()%(decimalDigits[ONES_IDX]>0 ? 2 : 3);
    if (digitIndex == TENS_IDX && decimalDigits[TENS_IDX] == 2) {
        digitIndex -= 1 + 2*(i%2);
    }

    decimalDigits[digitIndex]++;  //Negative array index here
}
for(int digitIncrease=0;digitIncrease 0?2:3);
如果(数字索引==TENS\u IDX&&decimalDigits[TENS\u IDX]==2){
数字索引-=1+2*(i%2);
}
小数位数[数字索引]+//这里是负数组索引
}

我至少要开始看看那个街区,也就是说,它不容易理解,可能是你逻辑上的错误

您正在访问小数位数
的越界元素

在UB之前试试这三行

        if (digitIndex < 0 || digitIndex >= 3) {
            fprintf(stderr, "error %d\n", __LINE__);
        }
        decimalDigits[digitIndex]++;
if(数字索引<0 | |数字索引>=3){
fprintf(标准,“错误%d\n”,第行);
}
小数位数[数字索引]+;

我运行了您在OS X上使用clang编译的代码,但您所描述的并没有发生。它也不会在任何时候重复。我想是你。因为你可能正在生成索引398和399,而这些索引都是无用的小数。如果你想随机增加你的数字1、10或100,那么只需让
results[rand(400)]+=10*rand(0,2)我猜你在
小数位数中使用了一个负索引,它正在写入
结果的末尾(未定义的行为)。啊。是的,它应该是
digitIndex=digitIndex-1+2*(i%2)
。谢谢。@RotatingPieces修复了负数组索引,但您的逻辑仍然允许您的位置多次递增。
        if (digitIndex < 0 || digitIndex >= 3) {
            fprintf(stderr, "error %d\n", __LINE__);
        }
        decimalDigits[digitIndex]++;