2015-01-10 7 views
-2

그래서, 내가 정의한 템플릿 클래스 후.힙 손상이 감지 : 내가 어떤 연산자를 오버로드 할 시도 후 정상 블록()

template <typename T> class Set 
    { 
    public: 
     Set(void); 
     Set(Set&); 
     ~Set(void); 
     bool contains(T elem); 
     bool add(T elem); 
     bool remove(T elem); 
     bool add(T* tab, int size); 
     T* getSet(); 
     int size(); 
     Set<T> &operator+(Set<T> &snd); 
     Set<T> &operator-(Set<T> &snd); 
    private: 
     T *elements; 
     int numOfElem; 
    }; 

요소를 추가 메서드로 추가하려고하면 모든 것이 정상적으로 작동합니다.

template<typename T> 
    bool Set<T>::add(T elem) 
    { 
     bool found = false; 
     for(int i =0; !found && i<numOfElem; i++){ 
      if(elem == elements[i]) found = true; 
     } 
     if(!found){ 
      numOfElem++; 
      T* tmp = new T[numOfElem]; 
      for(int i =0; i<numOfElem-1; i++){ 
       tmp[i] = elements[i]; 
      } 
      tmp[numOfElem-1] = elem; 
      delete[] elements; 
      elements = tmp; 
     } 
     return !found; 
    } 

    template<typename T> 
    bool Set<T>::add(T* myArray, int size) 
    { 
     bool result = false; 
     for(int i =0; i<size; i++){ 
      add(myArray[i]); 
     } 
     return result; 
    } 
template<typename T> 
Set<T>& Set<T>::operator+(Set<T> &snd) 
{ 
    Set *temp = new Set(*this); 
    temp->add(snd.getSet(), snd.size()); 
    return *temp; 
} 
template<typename T> 
void Set<T>::operator=(Set<T> &snd) 
{ 
    numOfElem = snd.numOfElem; 
    elements = new T[numOfElem]; 
    for(int i =0; i < numOfElem; i++){ 
     elements[i] = snd.elements[i]; 
    } 
} 

template<typename T> 
int Set<T>::size() 
{ 
    return numOfElem; 
} 
template<typename T> 
T* Set<T>::getSet() 
{ 
    return elements; 
} 
template<typename T> 
Set<T>::Set() 
{ 
    numOfElem = 0; 
    elements = nullptr; 
} 

template<typename T> 
Set<T>::Set(Set& old) 
{ 
    numOfElem = old.numOfElem; 
    elements = new T(numOfElem); 
    for(int i = 0; i< numOfElem; i++){ 
     elements[i] = old.elements[i]; 
    } 

} 

template<typename T> 
Set<T>::~Set() 
{ 
    numOfElem = 0; 
    delete[] elements; 
    elements = nullptr; 
} 

대신 + 연산자 (두 개의 개별 세트 추가)를 사용하면 배열 (15 줄)을 삭제하는 동안 오류가 발생합니다. 어떤 아이디어?

int main(){ 
    Set <char> set1, set2, set3; 
    char tab[] = {'a','d','f','g'} ; 
    set1.add(tab, 4); 
    char tab2[] = {'a','d','x','y','z'} ; 
    set2.add(tab2,5); 
    set3= set1+set2; 
} 
+4

로컬 객체에 대한 참조를 반환하는 것이 현명한 방법이 아닙니다. 컴파일러의 경고 ('operator +'에서'return temp')를 들었다. 템플릿 설정 설정 :: 연산자 + ( & SND 설정) '아무도'에 서명을 변경하는 것은 다 치지. – IInspectable

+0

@PiotrSzymczyk _ "좋아, 좋은 점은, 아직 문제가 해결되지 않습니다."_ 음, ** 당신은 ** A [MCVE]를 제공 할 것으로 예상된다 (http://stackoverflow.com/help/mcve)에 대한 제안을 거절하는 대신 문제를 해결하고 코드를 디버깅 할 다른 사용자를 기다리십시오! 불행히도 나는 다른 이유로 귀하의 질문에 대해 투표를 끝내지 만 사실상 당신은 중복에 대해 묻고 있습니다 : [지역 변수의 메모리를 범위 밖에서 액세스 할 수 있습니까?] (http://stackoverflow.com/questions/6441218)/can-a-local-variables- 접근 할 수있는 메모리 - 범위 밖). 나는 이것을 위해 당신의 질문을 1 위 자리에서 폭격 했어야했다. –

+2

나는 두 번 삭제하는 것 같아. 미가공 포인터가 있다면 3의 규칙을 고려해야합니다. 나는 단지 2를 본다. http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three –

답변

0

당신은 당신의 복사 생성자에 실수 있습니다

elements = new T(numOfElem); 

그것은 당신이 numOfEllem에 초기화 값을 하나 개의 변수 할당 new T(numOfElem);를 작성하여

elements = new T[numOfElem]; 

해야한다.

대신 배열의 표준 : : 벡터를 사용하면 이러한 문제를 방지 할 수 있습니다. 당신은 메모리를 할당하고 당신이 프로그램이 가상 메모리가 부족하여 실행할 수 있습니다 너무 자주 함수를 호출 그래서 만약 당신이 그것을 삭제하지

template<typename T> 
Set<T>& Set<T>::operator+(Set<T> &snd) 
{ 
    Set *temp = new Set(*this); 
    temp->add(snd.getSet(), snd.size()); 
    return *temp; 
} 

:

코드는 또한 더하기 연산자에서 메모리가 누수된다 uncaught std :: bad_alloc 예외로 인해 충돌합니다. 이 함수를 다음으로 변경하십시오.

template<typename T> 
Set<T> Set<T>::operator+(Set<T> &snd) 
{ 
    Set temp(*this); 
    temp.add(snd.getSet(), snd.size()); 
    return temp; 
} 
+0

스와핑은 파일 시스템이 지원하는 가상 메모리가있는 OS를 사용합니다. 일반적으로 이것은 필수적인 것은 아닙니다. 가상 메모리를 가정하면 응용 프로그램은 일반적으로 메모리가 아닌 주소 공간이 부족합니다. 결론은 똑같이 잘못되었습니다. 스와핑은 시스템 안정성에 영향을 미치지 않습니다.그리고 메모리를 누설해도 스와핑이 발생하지 않습니다. 메모리는 결국 페이징되고, 아무런 참조도 없으므로 절대로 다시 페이징되지 않습니다. 해당 단락을 모두 수정 (또는 제거) 할 수 있습니다. – IInspectable

+0

부정확 한 용어를 사용했기 때문에 스와핑으로 해당 부분을 제거했습니다. 나는 당신이 64 비트 프로그램에서 무한 루프로 그 추가를 실행할 때 물리적 인 운영 메모리의 크기가 주소 공간의 크기보다 훨씬 작아서 OS가 거대한 양의 페이지를 디스크에 스왑해야한다는 것을 의미했다. 그 동안 OS가 불안정해질 수 있습니다 (Windows 7에서 테스트했는데 컴퓨터를 리셋해야했습니다). 디스크의 스왑이 최대 용량에 도달하거나 프로그램의 가상 메모리가 가득 차게되면 프로그램이 결국 중단되지만 SSD 디스크가 없으면 실제로는 시간이 오래 걸립니다. –