linux上的分段错误(gcc)

linux上的分段错误(gcc),c,linux,gcc,valgrind,C,Linux,Gcc,Valgrind,我正在调试一个数字程序。它在Windows(Visual Studio编译器)上运行良好,提供了正确的结果 不幸的是,在使用gcc的Linux(Ubuntu12.04 x64)上,程序在进行了部分计算后出现了分段错误(我得到了部分结果) 我试图使用Valgrind来调试它,并找到一个可能会出现错误的地方 结果是: ==19565== Memcheck, a memory error detector ==19565== Copyright (C) 2002-2011, and GNU GPL'd

我正在调试一个数字程序。它在Windows(Visual Studio编译器)上运行良好,提供了正确的结果

不幸的是,在使用gcc的Linux(Ubuntu12.04 x64)上,程序在进行了部分计算后出现了分段错误(我得到了部分结果)

我试图使用Valgrind来调试它,并找到一个可能会出现错误的地方

结果是:

==19565== Memcheck, a memory error detector
==19565== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==19565== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==19565== Command: ./a.out
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E50: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0958 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E65: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0950 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E85: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0958 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402E9A: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0960 is not stack'd, malloc'd or (recently) free'd
==19565==
==19565== Invalid read of size 8
==19565==    at 0x402D82: MAXN(double, int, double, int*, double*,
int, double*, double*, double*, double*, int*, int*, double, double*,
int*, double) (in /home/muniek/Desktop/c_code/a.out)
==19565==    by 0x401991: main (in /home/muniek/Desktop/c_code/a.out)
==19565==  Address 0x54f0978 is 8 bytes before a block of size 1,696 alloc'd
==19565==    at 0x4C29DB4: calloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x404CC0: dvector(int, int) (in
/home/muniek/Desktop/c_code/a.out)
==19565==    by 0x400A62: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565==
==19565== HEAP SUMMARY:
==19565==     in use at exit: 1,704 bytes in 3 blocks
==19565==   total heap usage: 1,228,705 allocs, 1,228,702 frees,
9,826,265,416 bytes allocated
==19565==
==19565== 568 bytes in 1 blocks are still reachable in loss record 1 of 3
==19565==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x519D20A: __fopen_internal (iofopen.c:76)
==19565==    by 0x401100: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565== 568 bytes in 1 blocks are still reachable in loss record 2 of 3
==19565==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x519D20A: __fopen_internal (iofopen.c:76)
==19565==    by 0x401116: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565== 568 bytes in 1 blocks are still reachable in loss record 3 of 3
==19565==    at 0x4C2B6CD: malloc (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==19565==    by 0x519D20A: __fopen_internal (iofopen.c:76)
==19565==    by 0x40112C: main (in /home/muniek/Desktop/c_code/a.out)
==19565==
==19565== LEAK SUMMARY:
==19565==    definitely lost: 0 bytes in 0 blocks
==19565==    indirectly lost: 0 bytes in 0 blocks
==19565==      possibly lost: 0 bytes in 0 blocks
==19565==    still reachable: 1,704 bytes in 3 blocks
==19565==         suppressed: 0 bytes in 0 blocks
==19565==
==19565== For counts of detected and suppressed errors, rerun with: -v
==19565== ERROR SUMMARY: 2664 errors from 5 contexts (suppressed: 2 from 2)
我知道MAXN函数中存在一些问题(对吗?)

void MAXN(双放大器,整数ix,整数DX,整数NST,整数ETE,整数SP,整数C0,整数X0,整数CR,整数XC,整数N0,整数NC,整数T,
双精度*T0,整数*GPC,双精度PER)
{
双XCC,PFIX,TN;
int SX0,ST,FN,N;
ST=NINT((0.5/DX)+1);
FN=nin((1.0/DX)+1);
PFIX=3.0*PER/4.0;
TN=T;
SX0=NINT((X0[*NST]/DX)+1);
如果(SX0>SP+5)
(*NST)+;
//检查进入计算域的新波峰
对于(int i=ST;i ETE[i-1])&&(ETE[i]>ETE[i+1])&&(ETE[i]>0)和(ETE[i]>(AMP/4.0)))
{
XCC=双((i-1)*DX);
如果((XCC<(X0[*NC]-DX))&((TN-*T0)>PFIX))
{
*NC=*N0+1;
XC[*NC]=XCC;
CR[*NC]=ETE[i];
*T0=T;
转到停止;
}
}
}
stop://label 2继续
//在计算域内跟踪现有波峰
对于(int j=*NST;j ETE[i+1])&(ETE[i]>0))
{
NCC++;
CR[j]=ETE[i];
XC[j]=双((i-1)*DX);
}
如果(NCC==0)
{
对于(int k=N-10;k ETE[k-1])&(ETE[k]>ETE[k+1])&(ETE[k]>0))
{
CR[j]=ETE[k];
XC[j]=双((k-1)*DX);
}
}
}
}
}
//为下一步更新波峰和位置


对于(int i=*NST;i使用调试支持编译代码,并使用GDB运行代码。当SEGFULT发生时,您可以查看跟踪并查看错误发生的位置。

使用调试支持编译代码,并使用GDB运行代码。当SEGFULT发生时,您可以查看跟踪并查看错误发生的位置。

c使用调试支持编译代码并使用GDB运行代码。发生SEGFULT时,您可以查看跟踪并查看错误发生的位置。

使用调试支持编译代码并使用GDB运行代码。发生SEGFULT时,您可以查看跟踪并查看错误发生的位置。

是否正在编译您的代码带有调试信息的程序?这是通过运行带有
-g
选项的gcc启用的。如果您的程序有调试信息,valgrind将告诉发生无效访问的行号。有了调试信息,您使用gdb的时间也会轻松得多。

您是否使用调试信息编译程序?这是通过runn启用的使用
-g
选项编译gcc。如果您的程序有调试信息,valgrind会告诉行号无效访问发生的位置。使用调试信息,您使用gdb也会轻松得多。

是否使用调试信息编译程序?这是通过使用
-g
选项运行gcc启用的。如果您的程序如果有调试信息,valgrind将告诉行号在哪里发生了无效访问。有了调试信息,您使用gdb的时间也会轻松得多。

您是否使用调试信息编译程序?这是通过使用
-g
选项运行gcc启用的。如果您的程序有调试信息,valgrind将在e出现了无效访问。使用调试信息,您也可以更轻松地使用gdb。

它可能在Windows上按预期工作,但您可能仍在溢出缓冲区。有两种方法。一种是懒惰的方法,注释代码直到它停止崩溃,另一种是正确的方法,使用调试程序。我建议使用de调试代码时出错。此外,请确保使用调试符号编译代码,valgrind可能会给您提供行号而不是内存地址。@FiddlingBits可能是,但在Windows上,它每次都能正确运行,在Linux上甚至在Windows上once@Mr.Llama这是疯狂的-在使用调试选项编译之后…我不再有了SEGFULT O.O我需要检查结果,乍一看它们似乎还可以。它在Windows上可能会像预期的那样工作,但您可能仍在溢出缓冲区。有两种方法。一种是惰性方法,注释代码直到它停止崩溃,另一种是正确的方法,使用调试器。我建议使用调试器逐步完成整个过程代码。另外,请确保使用调试符号编译代码,valgrind可能会为您提供行号而不是内存地址。@FiddlingBits可能是,但在Windows上,它每次都能正确运行,在Linux上甚至在Windows上once@Mr.Llama这是疯狂的-在使用调试选项编译之后…我不再有segfault O.O,我需要检查结果,乍一看它们似乎还可以。它可能在Windows上按预期工作,但您可能仍在溢出缓冲区。有两种方法。一种是惰性方法,注释代码直到它停止崩溃,然后是正确的方法,使用调试器。我建议使用调试器逐步完成代码。另外,请确保com用调试符号堆积代码,valgrind可能会给出行号,而不是内存地址。@FiddlingBits可能是,但在Windows上,它每次都能正确运行,在Linux上,甚至在Windows上once@Mr.Llama这是疯狂的-在使用调试选项编译后…我不再有SEGFULT O.O。我需要在fir上检查结果看看他们似乎还可以。这在Windows上可能会像预期的那样工作,但你可能仍然在溢出缓冲区。有两种方法。一种是懒惰的方法,注释代码直到它停止崩溃,然后是正确的方法,使用调试器。我建议使用调试器逐步完成代码。另外,请确保使用debugg编译代码符号与价值
void MAXN (double AMP, int ix, double DX, int *NST, double* ETE, int SP, double* C0, double* X0, double* CR, double* XC, int *N0, int *NC, double T,
  double *T0, int* GPC, double PER)
{
  double XCC, PFIX, TN;
  int SX0, ST, FN, N;

  ST = NINT((0.5/DX)+1);
  FN = NINT((1.0/DX)+1);

  PFIX = 3.0*PER/4.0;
  TN = T;
  SX0 = NINT((X0[*NST]/DX)+1);

  if (SX0 > SP+5)
    (*NST)++;

  //checks for new wave crests entering the computational domain
  for (int i = ST; i <= FN; i++)
  {
    if ((ETE[i] > ETE[i-1]) && (ETE[i] > ETE[i+1]) && (ETE[i] > 0) && (ETE[i] > (AMP/4.0)))
    {
      XCC = double((i-1)*DX);
      if ((XCC < (X0[*NC]-DX)) && ((TN-*T0) > PFIX))
      {
        *NC = *N0 + 1;
        XC[*NC] = XCC;
        CR[*NC] = ETE[i];
        *T0 =T;
         goto stop;
      }
    }
  }
  stop://label 2 continue

  //tracks existing wave crests within the computational domain
  for (int j = *NST; j <= *NC; j++)
  {
    N = NINT((X0[j]/DX)+1);
    int NCC = 0;

    for (int i = (N - 1); i <= (N + ST); i++)
    {
      if ((ETE[i] > ETE[i-1]) && (ETE[i] > ETE[i+1]) && (ETE[i] > 0))
      {
        NCC++;
        CR[j] = ETE[i];
        XC[j] = double((i-1)*DX);
      }

      if (NCC == 0)
      {
        for (int k = N-10; k <= N+10; k++)
        {
          if ((ETE[k] > ETE[k-1]) && (ETE[k] > ETE[k+1]) && (ETE[k] > 0))
          {
            CR[j] = ETE[k];
            XC[j] = double((k-1)*DX);
          }
        }
      }
    }
  }
  //update wave crests and position for next step
  for (int i = *NST; i <= *NC; i++)
  {
    GPC[i] = NINT((XC[i]/DX)+1);
    X0[i] = XC[i];
    C0[i] = CR[i];
  }

  *N0 = *NC;
}