在我的程序中随机交换数组元素,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;
}
提前谢谢你:)
答案 0 :(得分:1)
而不是(i + 1),我尝试使用i,i + 2返回有效输出。但是对于i + 3向前发生无效输出
对于大于i+1
的任何内容(例如i+2
,i+3
等),结果索引j
来自:
int j = rand() % (i+2);
根据{{1}}返回的内容,可能超出数组rand()
的范围,因此可能会导致undefined behaviour。
有人可以解释为什么只能添加小于3的值吗?
这也不是正确的结论。如上所述,你不能添加任何更大的东西1.它恰好&#34;工作&#34;使用2(与任何未定义的行为一样,你只能依靠它而应该避免它。)
您可以打印arr
的值,并亲眼看看它是否超出了数组的范围。
答案 1 :(得分:1)
您的数组中包含n
个元素,这些元素的索引范围从0
到n-1
。
当您选择包含rand() % (i+1)
的新索引时,会产生从0
到i
的值。由于i
从n-1
开始并向下延伸到0
,因此会为您提供一个范围内的索引。
如果您对随机索引使用rand() % (i+2)
,则结果值的范围为0
到i+1
。在循环的第一次迭代i
等于n-1
,这意味着您可以得到值n
,这超出了数组的范围。
此时,问题只能在第一次迭代时发生,并且只有在随机值为n
的情况下才会发生,因此如果发生这种情况的机率大约是9次运行中的1次,那么它就会赢得#t一直发生。如果你使用i+3
,超出范围的几率会在循环的第一次迭代中加倍,而且可能在下一次迭代时发生。
这里生成随机值的正确方法是rand() % (i+1)
。任何大于i+1
的风险都会超出范围,风险会随着价值的增大而上升。