2012-02-10 1 views
2

많은 연구를 한 후에도 왜 valgrind에서이 오류가 발생했는지 알 수 없습니다. 클래스 스파이크 (의사 이중 링크 목록 구현)가 있습니다Valgrind 잘못된 읽기/쓰기 목록

class spike 
{ 
    int s_cell; 
    int s_begin; 
    int s_number; 
    int s_type; 
    spike *s_previous; 
    spike *s_next; 

    spike *s_origin; // pointer for original spike or itself 
        // (in the very first spike_data) 

    spike *s_derive; // pointer for the spike in the derived class 
        // (note, that sometimes there are 2 or more high 
        // order spike_data in parallel; the pointer is only to one) 
public: 
    spike(int c, int b, int n, int typ=c_normal) 
    { 
    s_cell = c; 
    s_begin = b; 
    s_number = n; 
    s_previous = NULL; 
    s_next = NULL; 
    s_derive = NULL; 
    s_origin = this; 
    s_type = typ; 
    } 

    ~spike() 
    { 
    kill(); 
    } 

그리고 클래스 spike_data. 그래서 여기있다 ...

Invalid read of size 4 
==2079== at 0x806B0DF: spike::kill() (spikes.cpp:674) 
==2079== by 0x8067D26: spike::~spike() (spike.h:288) 
==2079== by 0x806B174: spike_data::~spike_data() (spikes.cpp:689) 
==2079== by 0x805CB1F: spike_anal::~spike_anal() (spikea.cpp:151) 
==2079== by 0x8061C1E: statistical_analysis(spike_group*, spike_data*) (spikeg.cpp:264) 
==2079== by 0x804B37E: calculate_something(int, int) (all.cpp:422) 
==2079== by 0x8059805: real_main(int, char const*) (simple.cpp:742) 
==2079== by 0x804DC20: main (hello.cpp:66) 
==2079== Address 0x5d8f534 is 28 bytes inside a block of size 32 free'd 
==2079== at 0x4023881: operator delete(void*) (vg_replace_malloc.c:387) 
==2079== by 0x806B17C: spike_data::~spike_data() (spikes.cpp:697) 
==2079== by 0x805CB1F: spike_anal::~spike_anal() (spikea.cpp:151) 
==2079== by 0x8061C06: statistical_analysis(spike_group*, spike_data*) (spikeg.cpp:264) 
==2079== by 0x804B37E: calculate_something(int, int) (all.cpp:422) 
==2079== by 0x8059805: real_main(int, char const*) (simple.cpp:742) 
==2079== by 0x804DC20: main (hello.cpp:66) 
==2079== 
==2079== Invalid read of size 4 
==2079== at 0x806B0EC: spike::kill() (spikes.cpp:675) 
==2079== by 0x8067D26: spike::~spike() (spike.h:288) 
==2079== by 0x806B174: spike_data::~spike_data() (spikes.cpp:689) 
==2079== by 0x805CB1F: spike_anal::~spike_anal() (spikea.cpp:151) 
==2079== by 0x8061C1E: statistical_analysis(spike_group*, spike_data*) (spikeg.cpp:264) 
==2079== by 0x804B37E: calculate_something(int, int) (all.cpp:422) 
==2079== by 0x8059805: real_main(int, char const*) (simple.cpp:742) 
==2079== by 0x804DC20: main (hello.cpp:66) 
==2079== Address 0x5d8f534 is 28 bytes inside a block of size 32 free'd 
==2079== at 0x4023881: operator delete(void*) (vg_replace_malloc.c:387) 
==2079== by 0x806B17C: spike_data::~spike_data() (spikes.cpp:697) 
==2079== by 0x805CB1F: spike_anal::~spike_anal() (spikea.cpp:151) 
==2079== by 0x8061C06: statistical_analysis(spike_group*, spike_data*) (spikeg.cpp:264) 
==2079== by 0x804B37E: calculate_something(int, int) (all.cpp:422) 
==2079== by 0x8059805: real_main(int, char const*) (simple.cpp:742) 
==2079== by 0x804DC20: main (hello.cpp:66) 
==2079== 
==2079== Invalid write of size 4 
==2079== at 0x806B10A: spike::kill() (spikes.cpp:685) 
==2079== by 0x8067D26: spike::~spike() (spike.h:288) 
==2079== by 0x806B174: spike_data::~spike_data() (spikes.cpp:689) 
==2079== by 0x805CB1F: spike_anal::~spike_anal() (spikea.cpp:151) 
==2079== by 0x8061C1E: statistical_analysis(spike_group*, spike_data*) (spikeg.cpp:264) 
==2079== by 0x804B37E: calculate_something(int, int) (all.cpp:422) 
==2079== by 0x8059805: real_main(int, char const*) (simple.cpp:742) 
==2079== by 0x804DC20: main (hello.cpp:66) 
==2079== Address 0x5d8f534 is 28 bytes inside a block of size 32 free'd 
==2079== at 0x4023881: operator delete(void*) (vg_replace_malloc.c:387) 
==2079== by 0x806B17C: spike_data::~spike_data() (spikes.cpp:697) 
==2079== by 0x805CB1F: spike_anal::~spike_anal() (spikea.cpp:151) 
==2079== by 0x8061C06: statistical_analysis(spike_group*, spike_data*) (spikeg.cpp:264) 
==2079== by 0x804B37E: calculate_something(int, int) (all.cpp:422) 
==2079== by 0x8059805: real_main(int, char const*) (simple.cpp:742) 
==2079== by 0x804DC20: main (hello.cpp:66) 

을 코드 indigest 경우 죄송합니다

class spike_data 
{ 
protected: 
    int sd_mode; 
    int sd_size; 
    int sd_number;  // the whole number of spikes 
    int sd_file;  // the number of files for analysis 
    int *sd_file_name; // the names of files used in the analysis 
    int sd_cells;  // the whole number of different cells 

    spike **sd_array; // array of all spikes 
    spike *sd_first[c_maxcells]; // array of the first entries of spikes 
    spike **sd_file_st; // spikes in array for indication of beginning of the new files 

// And here is the part that's getting the error 
// (it is happening when i try to release) 
void spike::kill() 
{ 
    // delete a cell from all references and t becomes "dead" 
    // actual release of memory is done in renumerate 
    try 
    { 
    if (s_previous != NULL) 
     s_previous->s_next = s_next; 
    if (s_next != NULL) 
     s_next->s_previous = s_previous; 
    if (s_origin && s_origin != this) 
    { 
     int tmp = 1; 
    while(tmp == 1) { 
     if (s_origin != NULL) { 
      if (s_origin->s_derive != NULL) { // LINE 674 
       if (s_origin->s_derive != this) { // LINE 675 
         s_origin=s_origin->s_derive; 
        } 
        else tmp = 0; 
       } 
      else tmp = 0;      
        } 
      else tmp = 0; 
    } 

     s_origin->s_derive=NULL; // LINE 685 
    } 
    } 
    catch (...) 
    { 
    } 
    s_next = NULL; 
    s_previous = NULL; 
    s_origin = NULL; 
} 


spike_data::~spike_data() 
{ 

if(sd_array!=NULL) 
{ 
    for(int i=0;i<sd_number;i++) 
     delete sd_array[i]; // LINE 697 

    delete[] sd_array; 
    sd_array=NULL; 
} 
if(sd_file_st!=NULL) 
{ 
    delete[] sd_file_st; 
    sd_file_st=NULL; 
} 
if(sd_file_name!=NULL) 
{ 
    delete[] sd_file_name; 
    sd_file_name=NULL; 
} 
} 

, 그것은 내 아니지만, 그것은 여전히 ​​괜찮습니다. 내가 spike_data를 죽이고 싶을 때, 내가 sd_array [i]를 호출 할 때마다 spike => kill()의 소멸자를 호출 할 때마다 마지막에이 코드 버그가 있습니다. 실행 중에 여러 번 사용되었고 모든 계산이 완료되고 메모리를 해제해야하는 시점에서 작동하지 않습니다. 나는 s_origin-> s_derive = NULL을 넣을 때 문제가 있다고 생각한다. 하지만 u는 더 많은 코드가 필요하면

단지 :

이 코드에 들어갈 수있을만큼 용기있는 사람들을 위해 당신에게 많이 감사 요청 ... 그것을 잡을 수 없습니다!

좋은 주 말

니코 스파이크에 대한 기본 복사 생성자는 당신이 그것을 몰래 호출 된 것을 좋은 가능성이있다

+1

OMG 게시하기 전에 코드를 살펴보십시오! 나는 그것을 편집하고있다. – Eregrith

+0

코드 스타일이 클래스의 첫 번째 줄에서 작동하지 않는 이유를 모르겠다. 죄송합니다. 아니면 스타일에 대해 이야기하고 있습니까? 네, 정말 고문이에요. 이 코드 조각을 더보기 좋은 것으로 바꾸려고합니다. 러시아 출신입니다 ^^ – Nikkolasg

+0

변경했습니다. 더 좋습니다. 새 라인 부재로 인해 실패했습니다. ^^ – Eregrith

답변

1

. 이 경우 첫 번째 소멸자가 제대로 실행될 수 있지만 두 번째 호출은 valgrind가 게시 한 것과 같은 메시지를 덤프합니다. 당신이 C++ (11)를 사용하는 경우이는 경우가 있는지 확인하기 위해

, 추가

public: 
    spike(const spike& rhs) = delete; 

를하고 코드가 나타내는 컴파일 실패 당신이 당신의 자신의 사본을 작성의 필요성 건설자.

이 아닌의 C++ 11을 사용하는 경우 사용자 고유의 복사 생성자를 작성하고 디버깅 중에 중단 점이 있는지 확인할 수 있습니다.

+0

저는 spike :: spike (const spike & rhs) {}와 같은 복사 생성자를 생성하고 그것에 대해 말한대로 휴식을 취합니다. 하지만 프로그램이 멈추지 않으므로 복사 생성자를 호출하지 않습니다 ... :/thx anyway !! – Nikkolasg

+0

원래 프로그래머는 memcpy cmd (copy 생성자 대신 old 코드)를 많이 사용합니다. 예 : dop = new spike * [sd_size]; memcpy (dop, sd_array, sizeof (spike *) * sd_number); 나는 그것에 대해 연구 할 것이다. – Nikkolasg

+0

spikes.cpp : 689 및 spikes.cpp : 697에 중단 점 배치 - 중단 점을 누르면 릴리스 될 메모리 위치가 인쇄됩니다. 그런 다음 중단 점을 조건부 중단 점으로 변경하여 변수가 해당 주소 인 경우 중지하십시오. 그 지점을 두 번째로 치면 콜 스택으로 올라가면 문제가 보입니다. 여기서 결정 론적 메모리 버그가 있습니다. 디버그하기가 어렵지 않아야합니다 (콜 스택에 스파게티 코드가 없으면). 이걸 잡으려면 눈과 두뇌를 조금 사용해야합니다. – kfmfe04