0

私は次のファンクターを持っています:

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;
      }
    }
};

これは厳密な弱順序であると想定されており、デバッグ目的ではこれほど長くなります(1行のみの場合もあります)。

私はこのファンクターを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はリストであり、クラスRequestは次のようになります。

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();
};

何が起こっているのかについての仮説を立てることができればいいのですが、実際にはわかりません。ポインタを事前に感謝します。

4

4 に答える 4

5

機能的に言​​えば、投稿したコードに問題はありません。これが完全なテスト プログラムです。空白を埋めただけで、コードはまったく変更していません。

#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

セットには 3 つすべてが格納された状態になり、比較ログは賢明な動作を示していることに注意してください。

編集:

あなたのバグは次の行にあります:

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

disk.addFile(&temp_file);

ローカル オブジェクトのアドレスを取得しています。ループのたびにそのオブジェクトが破棄され、次のオブジェクトがまったく同じスペースに割り当てられます。そのため、ループの最後には最後のオブジェクトのみが存在し、その同じオブジェクトに複数のポインターを追加しました。ループの外では、オブジェクトが存在しないため、すべての賭けがオフになります。

各 SimulatedDiskFile を new で割り当てるか (私のテストのように、ただし、いつ削除するかを判断する必要があります)、またはポインターをまったく使用しないでください (問題の制約に適合する場合ははるかに簡単です)。

于 2009-06-16T12:18:39.433 に答える
2

そして、ここに問題があります:

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

すぐに破棄される変数へのポインターを追加しています。SDF オブジェクトを動的に作成する必要があります。

于 2009-06-16T12:24:17.643 に答える
1
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 オブジェクトを作成し、それ以外の場合は、オブジェクトが小さい場合はプッシュし、値でセットに格納します。

于 2009-06-16T12:25:51.137 に答える
0

@Earwickerに同意します。すべてが良さそうです。all_requests の中を見たことがありますか? そこにあるすべてのファイル名が同じで、他のすべてが正常に機能している可能性がありますか? (ここで大声で考えているだけです)

于 2009-06-16T12:25:51.853 に答える