C++实现复数离散傅里叶变换(DFT)运行时出现段错误如何解决
问题根因
- 触发段错误的核心原因是vector下标越界访问:
代码中输出结果的循环条件写为for (unsigned int k = 0; k <= result_x.size(); k++),C++ 中vector的下标从0开始计数,合法下标范围是0 到 result_x.size()-1,当k等于result_x.size()时访问result_x[k]已经超出了vector的合法内存范围,直接触发非法内存访问导致段错误。 - 额外隐患:你在同一个循环中用相同下标k访问
result_y[k],如果x.txt和y.txt的行数不一致,会导致result_x和result_y长度不同,也会触发越界访问。 - 你看到的gdb报错
this=0x0就是越界访问到了非法空地址对应的complex对象,这个问题和编译器版本无关,属于代码逻辑错误。
修复方案
- 首先修正循环条件,将
<=改为<,如果可以保证两个输入文件的长度一致,可以直接修改循环条件:
for (unsigned int k = 0; k < result_x.size(); k++)
- 如果两个输入文件长度可能不同,建议分开遍历两个结果vector分别写入对应文件,彻底规避越界风险:
// 写入x的DFT结果 for (unsigned int k = 0; k < result_x.size(); k++){ int freq = k; float amp_x = abs(result_x[k]); float phase_x = arg(result_x[k]); res_x << "[" << freq << ", " << amp_x << ", " << phase_x << "]" << endl; } // 写入y的DFT结果 for (unsigned int k = 0; k < result_y.size(); k++){ int freq = k; float amp_y = abs(result_y[k]); float phase_y = arg(result_y[k]); res_y << "[" << freq << ", " << amp_y << ", " << phase_y << "]" << endl; }
- 可选健壮性优化:读取文件完成后判断
x和y是否为空,避免DFT函数中计算phi时分母为0的问题。
可选功能修正:你当前的DFT计算逻辑存在错误,按照DFT公式
X[k] = sum_{n=0}^{N-1} x[n] * e^(-j2πkn/N),复数乘法展开后正确的实部、虚部计算应该为:re += x[n].real() * cos(phi) + x[n].imag() * sin(phi); im += -x[n].real() * sin(phi) + x[n].imag() * cos(phi);可以后续验证DFT输出正确性时调整。
内容的提问来源于stack exchange,提问作者Nghia Bui Gia
相关产品推荐
相关产品推荐

