内存管理问题 - “中止”、“总线”或“分段错误”错误且没有任何解释

问题描述 投票:0回答:1

我正在尝试用 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
c
1个回答
0
投票
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]));

您将知道哪些数据导致了错误

© www.soinside.com 2019 - 2024. All rights reserved.