【发布时间】:2018-09-24 03:17:14
【问题描述】:
我还没有找到这样的问题,但如果存在,请随时将我重定向到答案。
下面我已尽我所能复制我遇到的一个错误,代码尽可能少。 我在保留错误的同时尽可能多地删除了变量,并硬编码了复制它所需的值;我只留下了变量,这些变量必须是根据我的测试发生此错误的变量。首先,我传递一个值epsilon,一个double 值1.0/3.0。然后,我将它传递给a_function,它同时接受epsilon 和一些数组。我对部分输入数组执行了一些基本的复制,之后epsilon 的值会发生轻微的变化。下面是一段代码摘录,其中我删除了声明和include 语句。
int main(int argc, int argv[])
{
/* It doesn't matter what these arrays are filled with,
but they must be of length 13 */
int array1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int array2[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int array3[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int array4[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int a_value = 2;
double a_double= 1.0/3.0;
printf("a_double: %.10lf\n", a_double);
a_function(array1, array2, array3, array4, a_value, a_double);
return 0;
}
void a_function(int *array1, int *array2, int *array3, int *array4,
int a_value, double a_double)
{
int m = 1;
/* This occurs regardless of value assigned to m (provided the
for loop is appropriately changed to not go out of bounds) */
int temp_array1[m];
int temp_array2[m];
for(int i = 12; i < 13; i++)
{
temp_array1[i] = array1[i];
temp_array2[i] = array2[i];
}
printf("a_double: %.10lf\n", a_double);
}
运行此代码给出输出
$ ./a.out
a_double: 0.3333333333
a_double: 0.3333332539
似乎在以下情况下不会出现该错误:
- 数组的长度发生变化。
-
for循环的终止条件更改为最后一个元素以外的内容(例如,i < 12不会导致错误)。 - 所有包含的参数都将被删除。
- 当
m的值是硬编码时:m的值是什么无关紧要,但如果数组是根据它定义的,就会出现错误。 - 当我直接在
main中运行此代码时(即没有函数)。 - 当我的第一个
printf或a_double出现在函数入口时(即直接在int m = 1之前)。
此错误的原因可能是什么?我的猜测是它与 C 中的函数调用和临时变量有关,但我不知道。请让我知道是否有任何澄清。
【问题讨论】:
-
认为正式答案是 UB,可能发生的情况是,当您执行
temp_array2和temp_array1的越界分配时,您覆盖了保存输入参数的堆栈
标签: c arrays function memory-management double