2010-06-30 3 views
2

나는 내 코드에 문제가있는 것 같고 너희들이 내가 문제를 찾을 수 있도록 도와 줄 수 있는지 궁금해했다. gdb와 valgrind를 사용해 보았는데, 후자는 '더 유용하다'지만 여전히 내 버그를 고칠 수는 없다.g ++ Double 무료 또는 손상 ...하지만 어떻게?

다음은 내 수업에 대한 내 코드입니다 (이것은 내 아래로 축소 버전하지만 문제의 주요 핵심은 지속) :

/* Vector.h */

template<typename _TYPE_, Int _SIZE_> 
class Vec 
{ 
    public: 
      Vec(void); 
      Vec(const Vec<_TYPE_,_SIZE_>& vec); 
    virtual ~Vec(void); 

    Boolean    operator==(const Vec<_TYPE_,_SIZE_>& vec) const; 
    Boolean    operator!=(const Vec<_TYPE_,_SIZE_>& vec) const; 
    Boolean    operator< (const Vec<_TYPE_,_SIZE_>& vec) const; 
    Boolean    operator> (const Vec<_TYPE_,_SIZE_>& vec) const; 
    Boolean    operator<=(const Vec<_TYPE_,_SIZE_>& vec) const; 
    Boolean    operator>=(const Vec<_TYPE_,_SIZE_>& vec) const; 

    const _TYPE_&  operator[](const Int index) const; 
    _TYPE_&    operator[](const Int index); 

    Vec<_TYPE_,_SIZE_> operator+ (const Vec<_TYPE_,_SIZE_>& vec) const; 
    Vec<_TYPE_,_SIZE_> operator- (const Vec<_TYPE_,_SIZE_>& vec) const; 
    Vec<_TYPE_,_SIZE_> operator* (const _TYPE_ val) const; 

    _TYPE_    operator* (const Vec<_TYPE_,_SIZE_>& vec) const; 

    Vec<_TYPE_,_SIZE_>& operator+=(const Vec<_TYPE_,_SIZE_>& vec); 
    Vec<_TYPE_,_SIZE_>& operator-=(const Vec<_TYPE_,_SIZE_>& vec); 
    Vec<_TYPE_,_SIZE_>& operator*=(const _TYPE_ val); 

    private: 
    _TYPE_* __data; 
}; 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_>::Vec(void) 
{ 
    me.__data = new _TYPE_[_SIZE_]; 

    for(Int i = 0; i < _SIZE_; i++) 
    me.__data[i] = 0; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_>::Vec(const Vec<_TYPE_,_SIZE_>& vec) 
{ 
    me.__data = new _TYPE_[_SIZE_]; 

    for(Int i = 0; i < _SIZE_; i++) 
    me.__data[i] = vec[i]; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_>::~Vec(void) 
{ 
    printf("~Vec<%p>...", (void*)this); 

    if(me.__data != NOTHING) 
    delete[] me.__data; 
} 

/******************************************************************************* 
* COMPARISON OPERATORS. 
*******************************************************************************/ 

template<typename _TYPE_, Int _SIZE_> 
Boolean Vec<_TYPE_,_SIZE_>::operator==(const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    if(this == &vec) 
    return true; 

    for(Int i = 0; i < _SIZE_; i++) 
    if(me.__data[i] != vec[i]) 
     return false; 

    return true; 
} 

template<typename _TYPE_, Int _SIZE_> 
Boolean Vec<_TYPE_,_SIZE_>::operator!=(const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    return !(me == vec); 
} 

template<typename _TYPE_, Int _SIZE_> 
Boolean Vec<_TYPE_,_SIZE_>::operator< (const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    if(this == &vec) 
    return false; 

    for(Int i = 0; i < _SIZE_; i++) 
    if(me.__data[i] >= vec[i]) 
     return false; 

    return true; 
} 

template<typename _TYPE_, Int _SIZE_> 
Boolean Vec<_TYPE_,_SIZE_>::operator> (const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    if(this == &vec) 
    return false; 

    for(Int i = 0; i < _SIZE_; i++) 
    if(me.__data[i] <= vec[i]) 
     return false; 

    return true; 
} 

template<typename _TYPE_, Int _SIZE_> 
Boolean Vec<_TYPE_,_SIZE_>::operator<=(const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    return !(me > vec); 
} 

template<typename _TYPE_, Int _SIZE_> 
Boolean Vec<_TYPE_,_SIZE_>::operator>=(const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    return !(me < vec); 
} 

/******************************************************************************* 
* ELEMENT ACCESSORS. 
*******************************************************************************/ 

template<typename _TYPE_, Int _SIZE_> 
const _TYPE_& Vec<_TYPE_,_SIZE_>::operator[](const Int index) const 
{ 
    return me.__data[index]; 
} 

template<typename _TYPE_, Int _SIZE_> 
_TYPE_& Vec<_TYPE_,_SIZE_>::operator[](const Int index) 
{ 
    return me.__data[index]; 
} 


/******************************************************************************* 
* ARITHMATICAL OPERATORS. 
*******************************************************************************/ 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_> Vec<_TYPE_,_SIZE_>::operator+ (const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    Vec<_TYPE_,_SIZE_> tmp; 

    for(Int i = 0; i < _SIZE_; i++) 
    tmp[i] = me.__data[i] + vec[i]; 

    return tmp; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_> Vec<_TYPE_,_SIZE_>::operator- (const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    Vec<_TYPE_,_SIZE_> tmp; 

    for(Int i = 0; i < _SIZE_; i++) 
    tmp[i] = me.__data[i] - vec[i]; 

    return tmp; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_> Vec<_TYPE_,_SIZE_>::operator* (const _TYPE_ val) const 
{ 
    Vec<_TYPE_,_SIZE_> tmp; 

    for(Int i = 0; i < _SIZE_; i++) 
    tmp[i] = me.__data[i] * val; 

    return tmp; 
} 

template<typename _TYPE_, Int _SIZE_> 
_TYPE_ Vec<_TYPE_,_SIZE_>::operator* (const Vec<_TYPE_,_SIZE_>& vec) const 
{ 
    _TYPE_ tmp = 0; 

    for(Int i = 0; i < _SIZE_; i++) 
    tmp += me.__data[i] * vec[i]; 

    return tmp; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_>& Vec<_TYPE_,_SIZE_>::operator+=(const Vec<_TYPE_,_SIZE_>& vec) 
{ 
    for(Int i = 0; i < _SIZE_; i++) 
    me.__data[i] = me.__data[i] + vec[i]; 

    return me; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_>& Vec<_TYPE_,_SIZE_>::operator-=(const Vec<_TYPE_,_SIZE_>& vec) 
{ 
    for(Int i = 0; i < _SIZE_; i++) 
    me.__data[i] = me.__data[i] - vec[i]; 

    return me; 
} 

template<typename _TYPE_, Int _SIZE_> 
Vec<_TYPE_,_SIZE_>& Vec<_TYPE_,_SIZE_>::operator*=(const _TYPE_ val) 
{ 
    for(Int i = 0; i < _SIZE_; i++) 
    me.__data[i] = me.__data[i] * val; 

    return me; 
} 

/******************************************************************************* 
******************************************************************************** 
** 3D Vector Class. 
******************************************************************************** 
*******************************************************************************/ 

template<typename _TYPE_> 
class Vec3 : public Vec<_TYPE_,3> 
{ 
    public: 
    Vec3(_TYPE_ x = 0, _TYPE_ y = 0, _TYPE_ z = 0); 
    Vec3(const Vec<_TYPE_,3>& vec); 
    ~Vec3(void); 
}; 

#define Vec3_f Vec3<Float> 

template<typename _TYPE_> 
Vec3<_TYPE_>::Vec3(_TYPE_ x, _TYPE_ y, _TYPE_ z) 
{ 
    me[XYZ::X] = x; 
    me[XYZ::Y] = y; 
    me[XYZ::Z] = z; 
} 

template<typename _TYPE_> 
Vec3<_TYPE_>::Vec3(const Vec<_TYPE_,3>& vec) 
{ 
    me[XYZ::X] = vec[XYZ::X]; 
    me[XYZ::Y] = vec[XYZ::Y]; 
    me[XYZ::Z] = vec[XYZ::Z]; 
} 

template<typename _TYPE_> 
Vec3<_TYPE_>::~Vec3(void) 
{ 

} 

/* PhysicalState. 시간 */

class PhysicalState 
{ 
    public: 
    PhysicalState(Vec3_f pos = Vec3_f(1,1,1), Vec3_f rot = Vec3_f(2,2,2), Vec3_f scale = Vec3_f(3,3,3)); 
    PhysicalState(const PhysicalState& phys); 
    ~PhysicalState(void); 

    PhysicalState& operator=(const PhysicalState& phys); 

    //Private: 
    Vec3_f position; 
    Vec3_f rotation; 
    Vec3_f scale; 
}; 

/* * PhysicalState.cpp/

PhysicalState::PhysicalState(Vec3_f pos, Vec3_f rot, Vec3_f scale) 
{ 
    me.position = pos; 
    me.rotation = rot; 
    me.scale = scale; 
} 

PhysicalState::PhysicalState(const PhysicalState& phys) 
{ 
    me.position = phys.position; 
    me.rotation = phys.rotation; 
    me.scale = phys.scale; 
} 

PhysicalState::~PhysicalState(void) 
{ 

} 

PhysicalState& PhysicalState::operator=(const PhysicalState& phys) 
{ 
    if(this != &phys) 
    { 
    me.position = phys.position; 
    me.rotation = phys.rotation; 
    me.scale = phys.scale; 
    } 

    return me; 
} 
길이 죄송/* Test.cpp에 */

int main(void) 
{ 
    PhysicalState ps; 

    return 0; 
} 

0

. 다음은 valgrind의 출력입니다.

[email protected]:~/Development/Projects/Engines/DarkDivine$ LD_LIBRARY_PATH=./Bin/Debug/ valgrind 
--track-origins=yes --leak-check=full ./Bin/Debug/Test 
    ==18549== Memcheck, a memory error detector 
    ==18549== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al. 
    ==18549== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info 
    ==18549== Command: ./Bin/Debug/Test 
    ==18549== 
    ==18549== Invalid free()/delete/delete[] 
    ==18549== at 0x40244D3: operator delete[](void*) (vg_replace_malloc.c:409) 
    ==18549== by 0x804905A: DarkDivine::Vec<float, 3>::~Vec() (Vector.h:91) 
    ==18549== by 0x8048FE3: DarkDivine::Vec3<float>::~Vec3() (Vector.h:282) 
    ==18549== by 0x4036B69: DarkDivine::PhysicalState::~PhysicalState() (PhysicalState.cpp:23) 
    ==18549== by 0x8048E77: main (Test.cpp:15) 
    ==18549== Address 0x4740128 is 0 bytes inside a block of size 12 free'd 
    ==18549== at 0x40244D3: operator delete[](void*) (vg_replace_malloc.c:409) 
    ==18549== by 0x804905A: DarkDivine::Vec<float, 3>::~Vec() (Vector.h:91) 
    ==18549== by 0x8048FE3: DarkDivine::Vec3<float>::~Vec3() (Vector.h:282) 
    ==18549== by 0x8048E3B: main (Test.cpp:13) 
    ==18549== 
    ==18549== Invalid free()/delete/delete[] 
    ==18549== at 0x40244D3: operator delete[](void*) (vg_replace_malloc.c:409) 
    ==18549== by 0x804905A: DarkDivine::Vec<float, 3>::~Vec() (Vector.h:91) 
    ==18549== by 0x8048FE3: DarkDivine::Vec3<float>::~Vec3() (Vector.h:282) 
    ==18549== by 0x4036B77: DarkDivine::PhysicalState::~PhysicalState() (PhysicalState.cpp:23) 
    ==18549== by 0x8048E77: main (Test.cpp:15) 
    ==18549== Address 0x4740168 is 0 bytes inside a block of size 12 free'd 
    ==18549== at 0x40244D3: operator delete[](void*) (vg_replace_malloc.c:409) 
    ==18549== by 0x804905A: DarkDivine::Vec<float, 3>::~Vec() (Vector.h:91) 
    ==18549== by 0x8048FE3: DarkDivine::Vec3<float>::~Vec3() (Vector.h:282) 
    ==18549== by 0x8048E04: main (Test.cpp:13) 
    ==18549== 
    ==18549== Invalid free()/delete/delete[] 
    ==18549== at 0x40244D3: operator delete[](void*) (vg_replace_malloc.c:409) 
    ==18549== by 0x804905A: DarkDivine::Vec<float, 3>::~Vec() (Vector.h:91) 
    ==18549== by 0x8048FE3: DarkDivine::Vec3<float>::~Vec3() (Vector.h:282) 
    ==18549== by 0x4036B9C: DarkDivine::PhysicalState::~PhysicalState() (PhysicalState.cpp:23) 
    ==18549== by 0x8048E77: main (Test.cpp:15) 
    ==18549== Address 0x47401a8 is 0 bytes inside a block of size 12 free'd 
    ==18549== at 0x40244D3: operator delete[](void*) (vg_replace_malloc.c:409) 
    ==18549== by 0x804905A: DarkDivine::Vec<float, 3>::~Vec() (Vector.h:91) 
    ==18549== by 0x8048FE3: DarkDivine::Vec3<float>::~Vec3() (Vector.h:282) 
    ==18549== by 0x8048DE2: main (Test.cpp:13) 
    ==18549== 
    ==18549== 
    ==18549== HEAP SUMMARY: 
    ==18549==  in use at exit: 36 bytes in 3 blocks 
    ==18549== total heap usage: 10 allocs, 10 frees, 120 bytes allocated 
    ==18549== 
    ==18549== 12 bytes in 1 blocks are definitely lost in loss record 1 of 3 
    ==18549== at 0x402532E: operator new[](unsigned int) (vg_replace_malloc.c:299) 
    ==18549== by 0x804923C: DarkDivine::Vec<float, 3>::Vec() (Vector.h:72) 
    ==18549== by 0x8048F76: DarkDivine::Vec3<float>::Vec3(float, float, float) (Vector.h:265) 
    ==18549== by 0x40367F1: DarkDivine::PhysicalState::PhysicalState(DarkDivine::Vec3<float>, DarkDivine::Vec3<float>, DarkDivine::Vec3<float>) (PhysicalState.cpp:6) 
    ==18549== by 0x8048DD7: main (Test.cpp:13) 
    ==18549== 
    ==18549== 12 bytes in 1 blocks are definitely lost in loss record 2 of 3 
    ==18549== at 0x402532E: operator new[](unsigned int) (vg_replace_malloc.c:299) 
    ==18549== by 0x804923C: DarkDivine::Vec<float, 3>::Vec() (Vector.h:72) 
    ==18549== by 0x8048F76: DarkDivine::Vec3<float>::Vec3(float, float, float) (Vector.h:265) 
    ==18549== by 0x403681A: DarkDivine::PhysicalState::PhysicalState(DarkDivine::Vec3<float>, DarkDivine::Vec3<float>, DarkDivine::Vec3<float>) (PhysicalState.cpp:6) 
    ==18549== by 0x8048DD7: main (Test.cpp:13) 
    ==18549== 
    ==18549== 12 bytes in 1 blocks are definitely lost in loss record 3 of 3 
    ==18549== at 0x402532E: operator new[](unsigned int) (vg_replace_malloc.c:299) 
    ==18549== by 0x804923C: DarkDivine::Vec<float, 3>::Vec() (Vector.h:72) 
    ==18549== by 0x8048F76: DarkDivine::Vec3<float>::Vec3(float, float, float) (Vector.h:265) 
    ==18549== by 0x4036843: DarkDivine::PhysicalState::PhysicalState(DarkDivine::Vec3<float>, DarkDivine::Vec3<float>, DarkDivine::Vec3<float>) (PhysicalState.cpp:6) 
    ==18549== by 0x8048DD7: main (Test.cpp:13) 
    ==18549== 
    ==18549== LEAK SUMMARY: 
    ==18549== definitely lost: 36 bytes in 3 blocks 
    ==18549== indirectly lost: 0 bytes in 0 blocks 
    ==18549==  possibly lost: 0 bytes in 0 blocks 
    ==18549== still reachable: 0 bytes in 0 blocks 
    ==18549==   suppressed: 0 bytes in 0 blocks 
    ==18549== 
    ==18549== For counts of detected and suppressed errors, rerun with: -v 
    ==18549== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 63 from 6) 

이 문제를 해결할 수있는 사람에게 미리 감사드립니다. GD.

추 신 : me = (* this); NOTHING = 0;

+3

작은 힌트 : 매크로 대신 typedef를 사용하여 템플릿 형식의 별칭을 만듭니다. – pmr

+2

STL의 벡터를 사용하지 않는 이유는 무엇입니까? 안전하고 버그가 없으며 빠릅니다. – Mau

+2

또 다른 작은 힌트 : C++의 구문에서 숨기려면 "나"와 같은 것을 정의하지 마십시오. 그것은 당신의 코드로 작업하기에 C++에 익숙한 사람들에게 훨씬 더 어렵게 만듭니다. 'this->'를 사용하십시오. 명시 적이어야하거나 구성원의 이름 일 필요가있는 경우에만 사용하십시오. 또한 C++에는 이미 NULL이 있습니다. 추가 아무것도 정의 할 필요가 없습니다. – Cogwheel

답변

7

벡터 클래스에는 포인터 멤버가 있지만 할당 연산자는 정의되어 있지 않습니다. 할당은 값으로 벡터를 전달하는 PhysicalState의 생성자에서 발생합니다.

std :: vector 또는 boost :: array를 사용하십시오. 부디.

4

Vec 클래스에는 맞춤 할당 연산자가없는 것 같습니다.

자동으로 생성 된 operator=()__data 포인터를 실제로 복사하지만 해당 배열의 요소는 복사해야합니다. 포인터가 복사되면 할당 후 Vec 개체에 동일한 포인터가 포함되어 문제가 발생할 수 있습니다.

사용자 지정 할당 연산자가 필요하다는 좋은 힌트는 이미 사용자 지정 복사본 생성자와 사용자 지정 소멸자가 필요하다는 것입니다. 그 중 하나가 필요하다면 보통 다른 두 개가 필요합니다 ("rule of three").

+0

그래, 그게 ... 학교 소년 오류 ... 이 추가로 고정 : VEC <_type _, _ SIZE _> & 연산자 = (CONST VEC <_type _, _ SIZE _> & VEC) { 경우 (!이 = VEC) {위한 (INT i = 0; i <_SIZE_; i ++) me .__ data [i] = vec [i]; } return me; } 감사합니다 !!!!! – DarkDivine

+0

@DarkDivine : 할당 연산자를 구현하는 Shoolboy 방식은 예외이며 예외는 아닙니다. 복사본 스왑 관용구를 찾으십시오. http://stackoverflow.com/questions/255612/c-dynamically-allocating-an-array-of-objects/255744#255744 –

2

PhysicalState는 Vec3을 사용하지만 복사 구성이 아닌 할당을 수행합니다.

Vec 기반 포인터를 사용하여 할당 연산자를 정의하지 않으므로 포인터가 원래의 초기화되지 않은 포인터를 잃어 버리고 건너 뛴 후 예기치 않은 삭제와 나중에 이중 삭제가 발생합니다.

복사 생성자와 일치하도록 vec/vec3에 연산자 =()을 만듭니다.