Domanda

Ho il seguente funzione:

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

Dovrebbe essere un ordinamento rigorosamente debole, ed è così lungo (potrebbe essere solo una riga) per scopi di debug.

Sto usando questo functor come funzione di confronto per uno stl :: set. Il problema è che inserisce solo il primo elemento. Aggiungendo l'output della console alla funzione di confronto, ho appreso che sta effettivamente confrontando il nome del file con se stesso ogni volta .

Altre righe pertinenti sono:

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet;

e

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

EDIT: il codice che chiama .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++;
}

Dove all_requests è un elenco e la classe Request è tale che:

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

Vorrei poter offrire la mia ipotesi su cosa sta succedendo, ma in realtà non ne ho idea. Grazie in anticipo per eventuali suggerimenti.

È stato utile?

Soluzione

Non c'è niente di sbagliato nel codice che hai pubblicato, funzionalmente parlando. Ecco un programma di test completo: ho solo riempito gli spazi vuoti, senza cambiare affatto il tuo codice.

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

Ottengo questo output:

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

Nota che il set finisce con tutte e tre le cose memorizzate al suo interno e la tua registrazione comparativa mostra un comportamento ragionevole.

Modifica

Il tuo bug è in queste righe:

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

disk.addFile(&temp_file);

Stai prendendo l'indirizzo di un oggetto locale. Ogni volta attorno al ciclo quell'oggetto viene distrutto e l'oggetto successivo viene allocato esattamente nello stesso spazio. Quindi alla fine del ciclo esiste ancora solo l'oggetto finale e hai aggiunto più puntatori allo stesso oggetto. Al di fuori del ciclo, tutte le scommesse sono disattivate perché ora non esiste alcun oggetto.

O alloca ogni SimulatedDiskFile con new (come nel mio test, ma poi dovrai capire quando eliminarli), oppure non usare affatto i puntatori (molto più facile se si adatta ai vincoli del tuo problema ).

Altri suggerimenti

Ed ecco il problema:

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

Stai aggiungendo un puntatore a una variabile che viene immediatamente distrutta. Devi creare dinamicamente i tuoi oggetti 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 andrebbe fuori ambito al momento della successiva iterazione nel ciclo while. È necessario modificare il codice di inserimento. Crea oggetti SimulatedDiskFile sull'heap e spingi diversamente se gli oggetti sono più piccoli, quindi archivia per valore nel set.

Accetto con @Earwicker. Tutto sembra a posto. Hai dato un'occhiata all'interno di all_requests? Forse tutti i nomi dei file sono uguali lì dentro e tutto il resto funziona bene? (sto solo pensando ad alta voce qui)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top