2017-12-01 52 views
0
void ChoreStack::add(int new_urgency_level, string new_job){ 
    for(int i = 0; i < length_; i++){ 
     Chore* temp_chore = chore_array_[i]; 
     if(temp_chore->level == new_urgency_level){ 
      temp_chore->joblist.append(new_job+"^"); 
     } 
     chore_array_[i] = temp_chore; 
     free(temp_chore); 
    } 
} 

안녕하세요, 이것은 Valgrind가 "크기 4의 잘못된 읽기"라고 말한 부분입니다. 이전에는 메모리 할당과 관련된 것을 전혀 배웠습니다. 누구든지 내게 왜 메모리 오류가 있고 그것을 고치는 지 자세히 설명해 주시겠습니까? 고맙습니다! 여기 Valgrind 오류 4 번 크기의 잘못된 읽기입니다.

내 선언입니다 :에 여기
class ChoreStack{ 
public: 
    ChoreStack(); 
    ~ChoreStack(); 
    void initialize(int new_urgency_level); 
    void add(int new_urgency_level, string new_chore); 
    void erase(int erase_level); 
    void print(); 
    void next(); 
int get_length(); 
private: 
    struct Chore{ 
     int level; 
     string joblist; 
    }; 
    Chore** chore_array_; 
    int length_; 
    string* split_joblist(string joblist); 
    int number_of_chores(string joblist); 
}; 

ChoreStack::ChoreStack(): chore_array_(nullptr), length_(0){ 
} 

ChoreStack::~ChoreStack(){ 
    delete[] chore_array_; 
} 

void ChoreStack::initialize(int new_urgency_level){ 
    delete[] chore_array_; 
    chore_array_ = new Chore*[new_urgency_level]; 
    for(int i = 0; i < new_urgency_level; i++){ 
     Chore* temp_chore = new Chore; 
     temp_chore->level = i+1; 
     temp_chore->joblist = ""; 
     chore_array_[new_urgency_level-i-1] = temp_chore; 
     delete temp_chore; 
    } 
    length_ = new_urgency_level; 
    cout << "New priority list with levels 1-" << length_ << " initialized." << endl; 
} 

이 ChoreStack에 관련된 부분이다 :: 추가() 함수) (주 :

: 여기
int main(){ 
ChoreStack c; 
string cmd_line; 
string* cmd_ptr = new string[3]; 
bool initialized = false; 
while(true){ 
    cout << "chores> "; 
    getline(cin, cmd_line); 
    int cmd_num = 0; 
    if(cmd_line.find_first_not_of("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890 ") != string::npos){ 
     cout << "Error: invalid input." << endl; 
    } else { 
     int begin_i = 0, space_occurence = 0; 
     unsigned int i = 0; 
     while(i <= cmd_line.length()){ 
      if(cmd_line[i] == ' ' || i == cmd_line.length()){ 
       space_occurence++; 
       cmd_num++; 
       if(space_occurence == 3){ 
        cmd_ptr[cmd_num-1] = cmd_line.substr(begin_i); 
        break; 
       } else { 
        cmd_ptr[cmd_num-1] = cmd_line.substr(begin_i, i - begin_i); 
       } 
       begin_i = i + 1; 
      } 
      i++; 
     } 
     string command = cmd_ptr[0]; 
     if(command == "init"){ 
      if(cmd_num == 1){ 
       cout << "Error: the number of priority levels is missing." << endl; 
      } else if(cmd_num > 2){ 
       cout << "Error: too much input for initializing." << endl; 
      } else { 
       if(cmd_ptr[1].find_first_not_of("1234567890") != string::npos){ 
        cout << "Error: the number of priority levels must be an integer larger than 0." << endl; 
       } else if(stoi(cmd_ptr[1]) < 1){ 
        cout << "Error: it is not possible to create a priority list with 0 or less levels." << endl; 
       } else { 
        c.initialize(stoi(cmd_ptr[1])); 
        initialized = true; 
       } 
      } 
     } else if(command == "add"){ 
      if(!initialized){ 
       cout << "Error: no priority list is initialized." << endl; 
      } else { 
       if(cmd_num == 1){ 
        cout << "Error: priority level and chore description are missing." << endl; 
       } else if(cmd_ptr[1].find_first_not_of("1234567890") != string::npos 
          || stoi(cmd_ptr[1]) < 1 
          || stoi(cmd_ptr[1]) > c.get_length()){ 
        cout << "Error: priority level must be an integer between 1-3." << endl; 
       } else if(cmd_num == 2){ 
        cout << "Error: chore description is missing." << endl; 
       } else { 
        c.add(stoi(cmd_ptr[1]), cmd_ptr[2]); 
       } 
      } 
     } 

오류 메시지입니다
invalid read of size 4: 
1.ChoreStack::add(int,std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>) 

2.main 

Address 0x5a9de70 is 0 bytes inside a block of size 40 free'd 
1. operator delete(void*) 

2. ChoreStack::initialize(int) 

3. main 

Block was alloc'd at 
1. operator new(unsigned long) 

2. ChoreStack::initialize(int) 

3. main 

이 양식과 동일한 형태로 많은 오류가 있습니다.

+0

오류를 복제하기에 충분한 코드가 필요할 것입니다. 또한 전체 'valgrind'오류 메시지를 보는 데 도움이됩니다. –

+0

안녕하십니까, QT 작성자의 오류 메시지를 복사하는 방법을 모르겠습니다. 나는 프로그래밍에 초보자입니다 ...... –

+0

안녕 데이비드, 방금 손으로 오류 메시지를 입력했습니다. 이제 제 코드를 분석하도록 친절하게 도와 주시겠습니까? 대단히 감사합니다 !!! –

답변

2

이것은 무료 액세스 후에 고전적인 액세스입니다.

void ChoreStack::initialize(int new_urgency_level){ 
    delete[] chore_array_; 
    chore_array_ = new Chore*[new_urgency_level]; 
    for(int i = 0; i < new_urgency_level; i++){ 
     Chore* temp_chore = new Chore; 
     temp_chore->level = i+1; 
     temp_chore->joblist = ""; 
     chore_array_[new_urgency_level-i-1] = temp_chore; 
     delete temp_chore; 
    } 

이 코드를 자세히 살펴보십시오. temp_chore이라는 포인터를 만듭니다. new으로 할당 한 객체를 가리 킵니다. 그런 다음 temp_chore의 값을 chore_array_에 복사합니다. 이제 배열에는 new으로 할당 한 객체에 대한 포인터가 있습니다.

그런데 delete 할당 한 개체. 이제는 chore_array_에 삭제 한 개체에 대한 포인터가 있습니다. 포인터가 더 이상 존재하지 않으므로이 포인터의 역 참조를 시도하는 것은 오류입니다.

는 그러나 add, 우리는이 :

Chore* temp_chore = chore_array_[i]; 
    if(temp_chore->level == new_urgency_level){ 

그래서 temp_chore->level가 객체의 temp_chore 점을 level 멤버에 액세스하기위한 시도이다. 하지만 당신은 그 물체 delete입니다.

원시 포인터 모음이 아닌 값 모음을 유지하면 훨씬 쉽게 찾을 수 있습니다.

+0

고맙습니다. 죄송합니다. "chore_array_ [i] -> level = new_urgency_level-i;"라고 말하면서 직접 돌려 주시면 죄송합니다. 프로그램이 더 이상 실행되지 않습니다 ... –

+0

모든 버그를 해결할 때까지 프로그램이 이상하고 예측할 수없이 작동합니다. –

+0

그래, 참으로 ... 지금까지 고생을 해왔다 ... 아무런 이유없이 "크기 8의 잘못된 읽기"외의 모든 오류를 해결할 수 있었다. ... –