【问题标题】:C: Function parameter input changes seemingly randomlyC:函数参数输入看似随机变化
【发布时间】:2018-09-24 03:17:14
【问题描述】:

我还没有找到这样的问题,但如果存在,请随时将我重定向到答案。

下面我已尽我所能复制我遇到的一个错误,代码尽可能少。 我在保留错误的同时尽可能多地删除了变量,并硬编码了复制它所需的值;我只留下了变量,这些变量必须是根据我的测试发生此错误的变量。首先,我传递一个值epsilon,一个double1.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 &lt; 12 不会导致错误)。
  • 所有包含的参数都将被删除。
  • m 的值是硬编码时:m 的值是什么无关紧要,但如果数组是根据它定义的,就会出现错误。
  • 当我直接在 main 中运行此代码时(即没有函数)。
  • 当我的第一个 printfa_double 出现在函数入口时(即直接在 int m = 1 之前)。

此错误的原因可能是什么?我的猜测是它与 C 中的函数调用和临时变量有关,但我不知道。请让我知道是否有任何澄清。

【问题讨论】:

  • 认为正式答案是 UB,可能发生的情况是,当您执行 temp_array2temp_array1 的越界分配时,您覆盖了保存输入参数的堆栈

标签: c arrays function memory-management double


【解决方案1】:

此代码具有未定义的行为:

  int m = 1;
  int temp_array1[m];  
  for(int i = 12; i < 13; i++)
  {
    temp_array1[i] = array1[i];
  }

循环执行一次,i 为 12。但是数组的长度为 1,所以写越界了。

【讨论】:

  • 谢谢!这是一个非常尴尬的错误。你知道为什么如果我在函数的第一行有一个printf,这个值就不会出现吗?或者这只是未定义行为的方式?
  • 未定义的行为是未定义的。
猜你喜欢
  • 1970-01-01
  • 2014-11-16
  • 2010-09-09
  • 1970-01-01
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多