【发布时间】:2018-05-07 15:53:24
【问题描述】:
我知道当遇到segmentation fault 11时,这意味着程序试图访问一个不允许访问的内存区域。
这里我尝试使用以下代码计算傅里叶变换。
当nPoints = 2^15(或者当然分数更少)时它运行良好,但是当我进一步将分数增加到2^16时它会损坏。我在想,是不是内存占用太多造成的?但是我在操作过程中并没有注意到太多的内存占用。虽然它使用递归,但它就地转换。我以为它不会占用太多内存。那么问题出在哪里?
提前致谢
PS:有一件事我忘了说,上面的结果是在 Max OS(8G 内存)上。
当我在 Windows(16G 内存)上运行代码时,它在 nPoints = 2^14 时损坏。所以这让我很困惑是否是内存分配引起的,因为Windows PC的内存更大(但真的很难说,因为两个操作系统使用不同的内存策略)。
#include <stdio.h>
#include <tgmath.h>
#include <string.h>
// in place FFT with O(n) memory usage
long double PI;
typedef long double complex cplx;
void _fft(cplx buf[], cplx out[], int n, int step)
{
if (step < n) {
_fft(out, buf, n, step * 2);
_fft(out + step, buf + step, n, step * 2);
for (int i = 0; i < n; i += 2 * step) {
cplx t = exp(-I * PI * i / n) * out[i + step];
buf[i / 2] = out[i] + t;
buf[(i + n)/2] = out[i] - t;
}
}
}
void fft(cplx buf[], int n)
{
cplx out[n];
for (int i = 0; i < n; i++) out[i] = buf[i];
_fft(buf, out, n, 1);
}
int main()
{
const int nPoints = pow(2, 15);
PI = atan2(1.0l, 1) * 4;
double tau = 0.1;
double tSpan = 12.5;
long double dt = tSpan / (nPoints-1);
long double T[nPoints];
cplx At[nPoints];
for (int i = 0; i < nPoints; ++i)
{
T[i] = dt * (i - nPoints / 2);
At[i] = exp( - T[i]*T[i] / (2*tau*tau));
}
fft(At, nPoints);
return 0;
}
【问题讨论】:
-
可能数组太大而无法在堆栈上分配。将它们设为全局或
static。 -
不要将
pow(2, 15);用于整数使用1<<15 -
out[i + step]:out的大小为n,i的大小最高可达n。这是个问题。 -
我很确定
PI应该由您的数学库提供... -
如果你想做一些 FFT 的东西,但不知道 C 语言的可用运算符,你可能会遇到困难......查看你的 C 教科书以了解按位移位运算符。
标签: c macos memory segmentation-fault fft