我正在尝试用 C 重写我的 python 代码,因为我的分析需要分析具有 1,000,000 x 6 数据点的 2,000 个文件。这样的文件要求使得 Python 中的分析非常慢,所以我一直在尝试用 C 重写它。该分析正在执行窗口快速傅里叶变换,我相信这在 C 中会更快,但每次尝试运行它都会给出以下之一3 个错误:“中止”、“总线”或“分段错误”
这是主要代码结构,并在重要位置添加注释:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h>
// constants setting up the array size
const int bins=30;
const int pno=1000000;
const int intv=2000;
// Simple function to assign bin number to each particle in a file
int sort(double x)
{
int j=0;
while (x>r_bin*(j+1))
{
j+=1;
}
return j;
}
int main(int argc, char **argv)
{
// Defining the arrays that will be saved to separate files
// I require this due to the complex values in the analysis,
// easier to save them separately
double binned_r[intv][bins];
memset( binned_r, 0, intv*bins*sizeof(double) );
double binned_c[intv][bins];
memset( binned_c, 0, intv*bins*sizeof(double) );
// Main loop that goes through the 2000 files
for (int k=0;k<intv;k++)
{
printf("%d\n", k);
double x[3];
FILE *f1;
char IC[999];
sprintf(IC,"NFW_12.30103_12.00000_4.544068_1.00.%06d",k);
f1 = fopen(IC,"r");
for (int j=0;j<pno;j++)
{
double a,b,c;
fscanf(f1,"%lf\t%lf\t%lf\n", &a,&b,&c);
x[0]=sqrt(a*a+b*b)/1000.;
x[1]=atan2(b,a);
x[2]=c/1000.;
binned_r[k][sort(x[0])]+=creal(x[2]*cexp(I*3*x[1]));
binned_c[k][sort(x[0])]+=cimag(x[2]*cexp(I*3*x[1]));
}
}
FILE *fill_r;
char NAM_r[999];
sprintf(NAM_r, "test_r.dat");
fill_r = fopen(NAM_r,"w");
FILE *fill_c;
char NAM_c[999];
sprintf(NAM_c, "test_c.dat");
fill_c = fopen(NAM_c,"w");
for (int k=0;k<intv;k++)
{
for (int l=0;l<bins;l++)
{
fprintf(fill_r,"%f\t", binned_r[k][l]);
fprintf(fill_c,"%f\t", binned_c[k][l]);
}
fprintf(fill_r,"\n");
fprintf(fill_c,"\n");
}
fclose(fill_r);
}
我请求帮助的主要原因是因为对此代码的每次更改都不会产生结果,所以我一直在理解这是否是一个基本语法问题,或者我请求的内存是否超出了我的笔记本电脑可以管理的范围。
即使删除了写入文件的部分,代码也会给出“中止”或“总线”错误,否则就是“分段错误”。我也尝试过使用
ulimit -s 65000
一开始似乎有帮助,但后来同样失败了。
编辑:
@Schwern 建议的更改(使用 -fsanitize=address 进行编译)导致了此错误,但是,我不确定如何解释它,因为我从未深入研究过 C
=================================================================
==71816==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x00016dd52ba0 at pc 0x0001020af698 bp 0x00016dd50d70 sp 0x00016dd50d68
READ of size 8 at 0x00016dd52ba0 thread T0
#0 0x1020af694 in main+0x828 (a.out:arm64+0x100003694)
#1 0x185163f24 (<unknown module>)
Address 0x00016dd52ba0 is located in stack of thread T0 at offset 7712 in frame
#0 0x1020aee78 in main+0xc (a.out:arm64+0x100002e78)
This frame has 8 object(s):
[32, 7712) 'binned_r' <== Memory access at offset 7712 overflows this variable
[7968, 7992) 'x'
[8032, 9031) 'IC'
[9168, 9176) 'a'
[9200, 9208) 'b'
[9232, 9240) 'c'
[9264, 9280) 'coerce'
[9296, 9307) 'NAM_r'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (a.out:arm64+0x100003694) in main+0x828
Shadow bytes around the buggy address:
0x00016dd52900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00016dd52980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00016dd52a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00016dd52a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00016dd52b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x00016dd52b80: 00 00 00 00[f2]f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
0x00016dd52c00: f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2 f2
0x00016dd52c80: f2 f2 f2 f2 00 00 00 f2 f2 f2 f2 f2 00 00 00 00
0x00016dd52d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00016dd52d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00016dd52e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==71816==ABORTING
zsh: abort ./a.out
binned_r[k][sort(x[0])]+=creal(x[2]*cexp(I*3*x[1]));
您不检查 sort(x[0]) 是否为
>= 0
和 <= bins
简单地调试你的程序
if((int)sort(x[0] < 0 || (int)sort(x[0] >= bins)
{
/* print your error message and exit the program */
}
binned_r[k][sort(x[0])]+=creal(x[2]*cexp(I*3*x[1]));
您将知道哪些数据导致了错误