문제

나는 다음과 같은 기능을 가지고있다 :

class ComparatorClass {
  public:
    bool operator () (SimulatedDiskFile * file_1, SimulatedDiskFile * file_2) {
      string file_1_name = file_1->getFileName();
      string file_2_name = file_2->getFileName();

      cout << file_1_name << " and " << file_2_name << ": ";

      if (file_1_name < file_2_name) {
        cout << "true" << endl;
        return true;
      }
      else {
        cout << "false" << endl;
        return false;
      }
    }
};

그것은 엄격한 약한 주문으로 여겨지며, 디버그 목적 으로이 길 (한 줄만)입니다.

이 functor를 stl :: set의 비교 기능으로 사용하고 있습니다. 문제는 첫 번째 요소 만 삽입됩니다. 비교 기능에 콘솔 출력을 추가함으로써 실제로 파일 이름을 자체로 비교하고 있음을 알게되었습니다. 매번.

다른 관련 라인은 다음과 같습니다.

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet;

그리고

// (FileSet files_;) <- SimulatedDisk private class member
void SimulatedDisk::addFile(SimulatedDiskFile * file) {
  files_.insert(file);
  positions_calculated_ = false;
}

편집하다: .addfile ()을 호출하는 코드는 다음과 같습니다.

current_request = all_requests.begin();
while (current_request != all_requests.end()) {
  SimulatedDiskFile temp_file(current_request->getFileName(), current_request->getResponseSize());
  disk.addFile(&temp_file);
  current_request++;
}

여기서 all_requests는 목록이고 클래스 요청은 다음과 같습니다.

class Request {
  private:
    string file_name_;
    int response_code_;
    int response_size_;

  public:
    void setFileName(string file_name);
    string getFileName();
    void setResponseCode(int response_code);
    int getResponseCode();
    void setResponseSize(int response_size);
    int getResponseSize();
};

나는 무슨 일이 일어나고 있는지에 대한 저의 저혈압을 제공 할 수 있기를 바랍니다. 그러나 실제로는 전혀 모릅니다. 포인터에 미리 감사드립니다.

도움이 되었습니까?

해결책

기능적으로 말하는 코드에는 아무런 문제가 없습니다. 다음은 완전한 테스트 프로그램입니다. 코드를 전혀 변경하지 않고 공백 만 채웠습니다.

#include <iostream>
#include <string>
#include <set>

using namespace std;

class SimulatedDiskFile
{
public:
    string getFileName() { return name; }

    SimulatedDiskFile(const string &n)
        : name(n) { }

    string name;
};

class ComparatorClass {
  public:
    bool operator () (SimulatedDiskFile * file_1, SimulatedDiskFile * file_2) {
      string file_1_name = file_1->getFileName();
      string file_2_name = file_2->getFileName();

      cout << file_1_name << " and " << file_2_name << ": ";

      if (file_1_name < file_2_name) {
        cout << "true" << endl;
        return true;
      }
      else {
        cout << "false" << endl;
        return false;
      }
    }
};

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet;

int main()
{
    FileSet files;

    files.insert(new SimulatedDiskFile("a"));
    files.insert(new SimulatedDiskFile("z"));
    files.insert(new SimulatedDiskFile("m"));

    FileSet::iterator f;
    for (f = files.begin(); f != files.end(); f++)
        cout << (*f)->name << std::endl;

    return 0;
}

나는이 출력을 얻는다 :

z and a: false
a and z: true
z and a: false
m and a: false
m and z: true
z and m: false
a and m: true
m and a: false
a
m
z

세트에는 세 가지가 모두 저장되어 있으며 비교 로깅은 현명한 동작을 보여줍니다.

편집하다:

당신의 버그는이 라인에 있습니다.

SimulatedDiskFile temp_file(current_request->getFileName(), current_request->getResponseSize());

disk.addFile(&temp_file);

당신은 로컬 객체의 주소를 취하고 있습니다. 루프 주위에 매번 그 물체가 파괴되고 다음 물체는 정확히 같은 공간에 할당됩니다. 따라서 최종 객체만이 루프 끝에 존재하며 동일한 객체에 여러 포인터를 추가했습니다. 루프 밖에서, 이제 모든 베팅은 꺼져 있지 않습니다. 이제 객체가 존재하지 않기 때문입니다.

각 시뮬레이션 된 DiskFile을 새 시뮬레이션 (내 테스트에서 예 : 삭제시기를 파악해야 함)을 할당하거나, 그렇지 않으면 포인터를 전혀 사용하지 않습니다 (문제의 제약 조건에 맞는 경우 훨씬 쉽습니다).

다른 팁

그리고 여기에 문제가 있습니다.

SimulatedDiskFile temp_file(current_request->getFileName(),
                                   current_request->getResponseSize());
disk.addFile(&temp_file);

즉시 파괴되는 변수에 대한 포인터를 추가하고 있습니다. SDF 객체를 동적으로 만들어야합니다.

urrent_request = all_requests.begin();
while (current_request != all_requests.end()) {
  SimulatedDiskFile temp_file(...blah..blah..); ====> pointer to local variable is inserted
  disk.addFile(&temp_file);
  current_request++;

}

temp_file은 다음 번 반복의 순간을 while 루프에서 범위를 벗어나게됩니다. 삽입 코드를 변경해야합니다. 힙에 SimulatedDiskFile 오브젝트를 작성하고 객체가 더 작은 경우 값을 값으로 저장하십시오.

@earwicker에 동의합니다. 모두 좋아 보인다. All_Requests 내부를 살펴 보셨습니까? 어쩌면 모든 파일 이름이 거기에서 동일하고 다른 모든 것이 잘 작동할까요? (여기서 큰 소리로 생각합니다)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top