【问题标题】:Segmentation Fault in Function returning Pointer to Array返回指向数组的指针的函数中的分段错误
【发布时间】:2013-01-05 07:02:27
【问题描述】:

我正在开发一个简单的软调制解调器程序。调制解调器旨在实现拨号调制解调器的音频 FSK,并且应该能够通过发出 DTMF 音调来发起电话呼叫。目前,我在使用会生成正弦值的函数时遇到一些问题。

 double* generate_sine( int numberOfElements, double amplitude, 
 double phase_in_degrees, double numberOfCycles)
{
static int i;

double *sine_output;
sine_output = malloc( numberOfElements*sizeof(double) ); 

for( i=0; i<numberOfElements; i++ )
{

     sine_output[i] = (amplitude*sin(( (2.0*M_PI*i*numberOfCycles)/(double)numberOfElements )+
     ((M_PI*phase_in_degrees)/180 )));

   }
return sine_output; 
}

函数中存在分段错误。在循环的第一次迭代之后,变量“i”似乎变成了一个指针,它的值为 4206692。sine_ptr 也有一个有效的地址,直到循环的第二次迭代,此时它变为 0 (NULL)。 这里是调用函​​数的地方。 DEFAULT_PHASE = 0.0

int main()
{
 int i;
     int numElements = 10;
 double* sine_ptr = generate_sine( numElements, 0.5, DEFAULT_PHASE, 440 );

  for( i=0; i<numElements; i++)
  {
    printf( "%e \n", *(sine_ptr + i ) );
  }
 free(sine_ptr);
 return 0;
}

在考虑了所有建议的编辑后,我能够解决我的代码中的问题,非常感谢你给我的任何帮助。

【问题讨论】:

  • 未定义的行为。当printf 需要一个 int 时,你传递了一个 double。
  • 我尝试指定我希望 printf() 显示一个 3.5%d 的数字。程序在运行时冻结。在函数“generate_sine()”的循环过程中,“sine_output”不知何故变成了一个空指针。

标签: c arrays pointers segmentation-fault


【解决方案1】:

编辑补充一点。

问题编号 1

您正在为 5 个元素分配足够的内存(numberOfElements 为 5)。然后,您尝试从初始点打印 10 个元素。最后 5 个元素将访问未分配的空间,并可能导致未定义的行为。包括分段错误。

问题编号 2

您没有释放指向已分配空间的指针,而是释放 10 个位置后的位置。如果解决了分段错误,这也会导致其他问题。

问题编号 3

这是次要事件之一。但是 sine_ptr 是 double,并且试图将其显示为 int 是未定义的。 将导致编译器警告。即使有警告,数字也被低估了。在您的情况下,输出将全为零。要查看正确的结果,请使用%lf

使用以下代码。

int main()
{
  int i;
  int numElements = 5;
  double* sine_ptr = generate_sine( numElements, 0.5, DEFAULT_PHASE, 440 );
   for( i=0; i<numElements; i++)
   {
     printf( "%lf \n", *(sine_ptr + i) );
   }
   free(sine_ptr);
   return 0;
}

【讨论】:

  • 为了完整起见,请包括 printf 类型不匹配。 UB 永远不能太少。
  • @Potatoswatter 格式化不会导致分段错误。可能是非法转换。但这些通常是警告,一些编译器甚至不会抱怨,除非你提出要求。
  • 程序仍然死机。
  • @user1505399 冻结是什么意思?分段错误消失了吗?
  • @Pavan,根据 C11 7.16.1.1/2(强调我的),使用 double 而不是 int 是未定义的:如果没有实际的下一个参数, 或者如果类型与实际下一个参数的类型不兼容 (根据默认参数提升), 行为未定义 ...(更多删减)。因此,您很可能看不到全零。
猜你喜欢
  • 2018-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 2016-02-19
  • 2021-06-25
  • 1970-01-01
相关资源
最近更新 更多