数组元素的随机交换 - 检测到堆栈粉碎

时间:2018-04-05 17:32:52

标签: c

在我的程序中随机交换数组元素,j的值确定如下:

    int j = rand() % (i+1);

而不是(i + 1),我尝试使用i,i + 2返回有效输出。 但是对于i + 3向前发生无效输出,有时会出现错误:

    *** stack smashing detected ***: ./a.out terminated
    Aborted (core dumped)

有人可以解释为什么只能添加小于3的值吗?

程序代码如下所示:

    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    void swap (int *a, int *b)
    {
     int temp = *a;
     *a = *b;
     *b = temp;
    }
    void printArray (int arr[], int n)
    {
     for (int i = 0; i < n; i++)
     printf("%d ", arr[i]);
     printf("\n");
    }
    void randomize ( int arr[], int n )
    {
     srand ( time(NULL) );
     for (int i = n-1; i > 0; i--)
         {
          int j = rand() % (i+1);
          swap(&arr[i], &arr[j]);
         }
    }
    int main()
    {
     int arr[] = {1, 2, 3, 4, 5, 6, 7, 8};
     int n = sizeof(arr)/ sizeof(arr[0]);
     randomize (arr, n);
     printArray(arr, n);
     return 0;
    }

提前谢谢你:)

2 个答案:

答案 0 :(得分:1)

  

而不是(i + 1),我尝试使用i,i + 2返回有效输出。但是对于i + 3向前发生无效输出

对于大于i+1的任何内容(例如i+2i+3等),结果索引j来自:

int j = rand() % (i+2);
根据{{​​1}}返回的内容,

可能超出数组rand()的范围,因此可能会导致undefined behaviour

  

有人可以解释为什么只能添加小于3的值吗?

这也不是正确的结论。如上所述,你不能添加任何更大的东西1.它恰好&#34;工作&#34;使用2(与任何未定义的行为一样,你只能依靠它而应该避免它。)

您可以打印arr的值,并亲眼看看它是否超出了数组的范围。

答案 1 :(得分:1)

您的数组中包含n个元素,这些元素的索引范围从0n-1

当您选择包含rand() % (i+1)的新索引时,会产生从0i的值。由于in-1开始并向下延伸到0,因此会为您提供一个范围内的索引。

如果您对随机索引使用rand() % (i+2),则结果值的范围为0i+1。在循环的第一次迭代i等于n-1,这意味着您可以得到值n,这超出了数组的范围。

此时,问题只能在第一次迭代时发生,并且只有在随机值为n的情况下才会发生,因此如果发生这种情况的机率大约是9次运行中的1次,那么它就会赢得#t一直发生。如果你使用i+3,超出范围的几率会在循环的第一次迭代中加倍,而且可能在下一次迭代时发生。

这里生成随机值的正确方法是rand() % (i+1)。任何大于i+1的风险都会超出范围,风险会随着价值的增大而上升。