Question

J'ai le foncteur suivant:

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

C’est censé être un ordre faible strict, et c’est aussi long (cela ne peut être qu’une seule ligne) à des fins de débogage.

J'utilise ce foncteur en tant que foncteur comparateur pour un stl :: set. Problème étant, il insère seulement le premier élément. En ajoutant la sortie de la console à la fonction de comparaison, j'ai appris que le nom de fichier était comparé à lui-même à chaque fois .

Les autres lignes pertinentes sont:

typedef set<SimulatedDiskFile *, ComparatorClass> FileSet;

et

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

EDIT: le code qui appelle .addFile () est:

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

Où all_requests est une liste et où la classe Request est telle que:

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

J'aimerais pouvoir proposer mon hypotèse sur ce qui se passe, mais je n'en ai aucune idée. Merci d’avance pour tous les conseils.

Était-ce utile?

La solution

Il n’ya rien de mal à ce que vous publiez du code, du point de vue fonctionnel. Voici un programme de test complet. J'ai seulement rempli les blancs, sans changer votre code.

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

Je reçois cette sortie:

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

Notez que l'ensemble contient les trois éléments stockés dans celui-ci et que votre journal de comparaison présente un comportement judicieux.

Modifier:

Votre bug est dans cette ligne:

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

disk.addFile(&temp_file);

Vous prenez l'adresse d'un objet local. Chaque fois autour de la boucle, cet objet est détruit et l'objet suivant est alloué exactement dans le même espace. Ainsi, seul le dernier objet existe toujours à la fin de la boucle et vous avez ajouté plusieurs pointeurs sur ce même objet. En dehors de la boucle, tous les paris sont désactivés car à présent aucun objet n'existe.

Attribuez un nouveau fichier à chaque fichier SimulatedDisk (comme dans mon test, mais vous devrez alors savoir quand le supprimer), ou n'utilisez pas de pointeur du tout (beaucoup plus facile si cela répond aux contraintes de votre problème ).

Autres conseils

Et voici le problème:

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

Vous ajoutez un pointeur sur une variable qui est immédiatement détruite. Vous devez créer dynamiquement vos objets 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 serait hors de portée lors de la prochaine itération dans la boucle while. Vous devez changer le code d'insertion. Créez des objets SimulatedDiskFile sur le tas et transmettez-les si les objets sont plus petits, puis stockés par valeur dans le jeu.

D'accord avec @Earwicker. Tout a l'air bien. Avez-vous examiné toutes les demandes? Peut-être que tous les noms de fichiers sont les mêmes et que tout le reste fonctionne bien? (juste penser à voix haute ici)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top