2015-01-26 2 views
3

누구나 gnuWin32를 사용할 때 런타임 오류가있는 이유를 알아낼 수 있습니까? GaussSeidel 함수에 주석을 달면 오류가 사라집니다. 온라인 GNU GCC v4.8.3 컴파일러를 사용해 보았는데 제대로 작동하는 것 같습니다. ideone.com의 C++ 14에서 런타임 오류가 두 번 무료 또는 손상되었음을 알려주었습니다. 그 오류로 고통받는 내 코드의 간단한 버전을 첨부했습니다. 감사. 함수 내부Double Free or Corrupt Error

#include <iostream> 
#include <cmath> 

void GaussSeidel(double** const aa, double* const bb, double* xvec, const int nn, int mm) 
{ 
    int i = 0, j = 0; 
    double *ynew=NULL, *yold=NULL, EE=20.0; 
    ynew=new double[nn]; 
    yold=new double[nn]; 

    while (mm > 0 && EE>0.00001) { 
     EE=0.0; 
     for (i = 0; i < nn; i++) { 
      yold[i]=ynew[i]; 
      ynew[i] = bb[i]/aa[i][i]; 
      for (j = 0; j < nn; j++) { 
       if (j == i) continue; 
       ynew[i] = ynew[i] - (aa[i][j] * xvec[j]/ aa[i][i]); 
       xvec[i] = ynew[i]; 
      } 
      if (std::abs(ynew[i]-yold[i])>EE) EE=std::abs(ynew[i]-yold[i]); 
     } 
     mm--; 
    } 
    std::cout << mm << " " << EE << std::endl; 

    for (j = 0; j < nn; j++) 
     xvec[i] = ynew[i]; 

    delete [] ynew; 
    delete [] yold; 
} 

int main (void) 
{ 
    int i, j; 
    const int Np=100; 
    double **Infl=NULL, *Source=NULL, *FpdPhi0=NULL; 

    Source=new double[Np]; 
    FpdPhi0=new double[Np]; 
    Infl = new double *[Np]; for(i = 0; i < Np; i++) Infl[i] = new double[Np]; 

    for (j=0; j<Np; j++){ 
     for (i=0; i<Np; i++){ 
      if (i==j){ 
       Infl[j][i]=1.0; 
      } 
      else { 
       Infl[j][i]=0.0; 
      } 
     } 
     Source[j]=4.0; 
     FpdPhi0[j]=0.1; 
    } 
    GaussSeidel(Infl, Source, FpdPhi0, Np, 300); 

    for(i = 0; i < Np; i++) delete [] Infl[i]; 
    delete [] Infl; 
    delete [] Source; 
    delete [] FpdPhi0; 

    return 0; 
} 
+5

'std :: vector'를 사용하여 모든 무의미한 수동 메모리 관리를 제거하십시오. – Chad

+2

또한, 함수에서'new []'를 두 번째 호출하면 예외가 발생하면 GaussSeidel에서 메모리 누수가 발생합니다. 'std :: vector'를 사용하여이 모든 문제를 피하십시오. – PaulMcKenzie

+0

for-loop 인덱스 변수의 범위를 제한하는 것이 좋습니다. – molbdnilo

답변

4

귀하의 마지막 루프는이 시점에서 아마 nn 동일과 범위를 벗어난 인덱스로 i를 사용합니다. 루프 변수 j을 사용하려고했을 것입니다.

은 결과, 당신은

+0

감사합니다. – mokk

0

나는 가능한 기여를 식별 할 수 있습니다 삭제 이전에 정의되지 않은 동작과 다른 내부적으로 정의 된 배열 중 하나 아마 손상입니다 xvec 배열 범위에서 액세스 할 수 있습니다.

ynew와 yold는 모두 기본 유형 (double)의 동적 할당 된 배열입니다. 이 함수의 첫 번째 동작은 루프에서 yold [i] = ynew [i]를 할당하는 것입니다 (여기서 i는 0에서 nn-1까지입니다)

문제는 연산자 new가 배열의 요소를 초기화한다는 것입니다. . 기본 유형 (double, int, pointers 등)의 기본 초기화는 초기화되지 않은 상태로 남겨 둡니다 (통계가 0으로 초기화되는 경우와 같은 특별한 경우는 제외).

"x = y"형식의 할당은 y에 대해 rvalue-to-lvalue 변환을 수행합니다 ("y의 값에 액세스하여 x에 동일한 값을 할당 할 수있는 복잡한 방법"이라고 함). rvalue-to-lvalue 변환은 초기화되지 않은 변수에 정의되지 않은 동작을합니다.

간단히 말해서 : GaussSeidel() 내에서 배열을 동적으로 할당 한 후에는 요소 값에 액세스하기 전에이를 초기화해야합니다.

빠른 탈지기에서 정의되지 않은 동작과 관련된 다른 명백한 문제는 선택하지 않았습니다.

operator new와 delete를 사용하여 직접 원숭이를 작성하는 대신 std :: vector를 사용하는 것이 좋습니다.

+0

답장을 보내 주셔서 감사합니다. 그럴거야. – mokk

관련 문제