2011-12-30 3 views
1

구조체 힙의 소멸자에 문제가 있습니다. 하나만 추가하고 사용하지 않을 경우 런타임 예외 (메모리 액세스)가 생성됩니다. 두 번째 날에하려고하고 내일은 마감일입니다.소멸자 정의를 추가하면 실행중인 예외가 발생합니다.

struct Heap 
{ 
     int n; 
     int* tab; 
     int* numerWKopcu; 

     Heap() { n=0; } 
     Heap (int size) { this->tab = new int[liczbaDomow]; n=0; this->numerWKopcu = new int[2000100];} 
     int max() { return tab[1]; } 
     bool empty() { return n==0; } 

     bool insert(int x) 
     { 
      n++; 
      tab[n]=x; 
      this->numerWKopcu[x] = n;//ZMIANA 
      upHeap(n); 
      return true; 
     }   

     bool delMin() 
     { 
      if (n<1) return false; 
      this->numerWKopcu[tab[n]] = 1; //ZMIANA 
      tab[1]=tab[n]; n--; 
      downHeap(1); 
      return true; 
     } 

    void upHeap(int x){ 
     int p; 
     int mem = tab[x]; 
     while (x>1) 
     { 
      p=x/2; 
      if (color[mem]>color[tab[p]]) break; 
      this->numerWKopcu[tab[p]] = x; //ZMIANA 
      tab[x]=tab[p]; 
      x=p; 
     } 
     this->numerWKopcu[mem] = x;//ZMIANA 
     tab[x]=mem; 
    } 

    void downHeap (int x) 
    { 
     int s=2*x; 
     int mem=tab[x]; 
     while(s<=n) 
     { 
      if (s+1<=n && color[tab[s]]>color[tab[s+1]]) 
       s++; 
      if (color[mem]>color[tab[s]]) 
      { 
       this->numerWKopcu[tab[s]] = x; //ZMIANA 
       tab[x]=tab[s]; 
       x=s; 
       s=2*x; 
      } 
      else break; 
     } 
     this->numerWKopcu[mem] = x;//ZMIANA 
     tab[x]=mem; 
    } 

    void write() 
    { 
     for (int i=1;i<=n;i++) printf ("%d) %d\n", i, tab[i]); 
     printf ("\n"); 
    }  

    void build() 
    { 
     int s = n; 
     for (s=n/2; s>=1; s--) downHeap(s); 
    } 
    /~Heap() { 
      delete []this->numerWKopcu; 
      delete []this-> tab; 
      }; 
}; 
+0

정확한 오류 메시지를 게시하십시오 ... – Nick

+0

이 코드는 불완전하며 (예 :'liczbaDomow'는 정의되지 않았습니다) 영어 이외의 변수 이름을 사용합니다. 두 가지 모두 함께 사람들이 당신을 도울 수 없게 만듭니다. – thiton

+0

디버거에서 실행 해 보았습니까? –

답변

2

코드 읽기가 조금 어렵다, 그러나 나는이 두 가지 문제를 참조하십시오

  • 당신은 너무 기본 - 건설 오브젝트를 파괴, 기본 생성자에 null로 포인터를 초기화하는 없습니다가 정의되지 않은 동작을 제공합니다;
  • 복사 생성자와 복사 할당 연산자를 정의하거나 제거하지 마십시오 (소멸자를 정의한 경우 항상 수행해야하는 것처럼 Rule of Three). 따라서 복사 된 객체를 삭제하면 정의되지 않은 동작이 발생합니다.

배열 경계 밖의 메모리에 액세스 할 수도 있습니다. valgrind과 같은 메모리 디버깅 도구를 사용하면 이러한 상황을 확인할 수 있습니다.

가장 간단한 해결책은 수동 관리 배열을 std::vector으로 바꾸는 것입니다. 자신의 소멸자를 작성하거나 의미를 복사하는 것에 대해 걱정할 필요가 없습니다. 또한 범위 확인 액세스를 제공하기 위해 [] (적어도 디버그 변형에서)이 아닌 at()을 사용할 수도 있습니다.

+0

그것은 ASD-Algorythms 및 데이터 구조를위한 것입니다. #include #include 나는 한계를 벗어났습니다. 나는 정의 된 소멸자를 초기화하지도 않는다. – Yoda

+0

@RobertKilar : 문제를 재현하는 짧은 컴파일 가능한 프로그램을 게시하면 도움이 될 수 있습니다. 그렇듯이 분명한 문제를 지적하는 것 이상의 것을하는 것은 어렵습니다. –

+0

확인. 고마워요. 방금 비용이 많이 드는 이유를 사용하지 않기로 결정했습니다. 방금 int [2000100]를 초기화 했으므로 필요한 모든 프로그램이 20 초에서 약 0.3 초까지 증가했습니다. 전체 코드는 394 줄이므로 읽을 수는 없습니다. 도움을 주셔서 감사합니다. – Yoda

1

기본 생성자에서 포인터를 초기화하지 않습니다. 기본 생성 된 힙을 파괴하려고 시도하면 소멸자의 임의의 메모리 영역을 삭제하려고 시도 할 것이므로 확실히 중단됩니다.

+0

절대 사용하지 않습니다. 나는 그것을 다음과 같이 변경했다 : \t \t Heap() {n = 0; this-> tab = 새로운 int [liczbaDomow]; this-> numerWKopcu = 새로운 int [2000100]; } 하지만 INSERT 함수에서 탭 [n] = x에서 오류가 동일하게 유지됩니다. x와 n은 컴퓨터에 알려지지 않았습니다. – Yoda

관련 문제