IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Vector qui fait planter à partir de 2048 éléments.


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Par défaut Vector qui fait planter à partir de 2048 éléments.
    Salut à tous.

    Bon, toujours dans un problème de lecture de fichiers, j'ai fais le programme suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    jour::jour(string directoryName)
    {
        string s = "/mnt/nas02/vista/fredarch/visu/" + directoryName + "t_traj.txt";
        cout << s << endl;
        ifstream file(s.c_str(), ios::in);
        trajectoire t;
        string str;
        vector<string> vec;
        int i=0;
     
        if (!file) //Si le fichier n'est pas lu...
        {
            cerr << "setDataTable : can't read " << directoryName << "." << endl;
            throw std::runtime_error("file not opened: "+ directoryName); //Erreur ! + envoi d'erreur.
        }
     
        string line;
        while (getline(file,line) && i< 100) //Tant qu'on lit des lignes dans le fichier.
        {
            istringstream iss(line);
            cout << i << endl;
            while (getline(iss, str, ' '))
            {
                if (str != "")
                {
                    vec.push_back(str);
                }
     
            }
            t.setTrajectory("/mnt/nas02/vista/fredarch/visu/" + directoryName + vec.at(19) + ".txt");
            //cout << vec.at(19) << endl;
            t.setCallSign(atoi(vec.at(4).c_str()));
            traj.push_back(t);
            vec.clear();
            i++;
        }
    }
    Tout ce petit bazar appartient à une classe "jour", qui n'a qu'en attribut un vector de trajectoires. J'ai déclaré dans un autre fichier une classe trajectoire est une classe qui prends en attribut un vector de points, une chaine de caractères et trois floats juste pour faire un code couleur.

    Mon code compile nickel et s'exécute bien, à quelques problèmes près. Rien à signaler jusqu’à ce que j'atteigne 1024 éléments. D'ailleurs si je choisis de ne prendre que les 100 premiers éléments par exemple le programme s'effectue sans soucis. A partir de 1024 éléments (une puissance de 2, comme par hasard), mon PC Debian commence à subir quelques ralentissements. A partir les 2048 éléments (1024 * 2, cooooooomme par hasard) le programme plante et finis par être "tué". Bref, j'ai pensé au début que j'avais juste fait une grosse pompe à CPU, mais on dirait plus au final un problème d'allocation.

    Comment puis-je résoudre ce problème ?

    Merci d'avance pour votre réponse.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    C'est pas vraiment lié au CPU, c'est plus la RAM. Tu es en train de tuer ta RAM.
    vector est pas magique, il assure des données contigues, soit un gros malloc. Il définit une taille, et si tu la dépasses, il en prévoit une plus grande, y copie l'intégralité, puis utilisera ce buffer. Jusqu'à ce qu'il déborde, donc en alloue un autre, etc...
    Arrivé à 1024 éléments (ce qui peut déjà être gros), tu débordes. Il en prévoit un plus grand, selon la règle d'agrandissement qu'il utilise. Peut-être 2048 éléments. Mais pendant un court instant tu as les 2 buffers alloués, don cautant de RAM utilisé.

    Pour correctement utilisé vector, on reserve la taille nécessaire, puis on push_back les données. Ca évite les réallocations à la volée.

    - Pourquoi utiliser vector ?
    - Pourquoi pas une list ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Parce que pour si peu d'éléments une liste est généralement beaucoup moins efficace qu'un vecteur.
    Et si tu passes ton programme dans vallgrind ou dans le mode sanatize de de clang.

    S'il y a des trucs dont je me méfierai, c'est de atoi, et de at().
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Par défaut
    Bon, du coup j'ai essayé d'allouer mon Vecteur avec la fonction reserve. Mais rien à faire ça plante encore. Par contre je vais pas le nier, y'a une amélioration : au lieu de ralentir à 1024 éléments, je ralentis à 1400 et quelques éléments. Mon programme à planté à 2166 éléments, alors que je suis supposé avoir une capacité de 5290 éléments (taille calculée via une fonction qui compte le nombre de ligne dans un fichier, donc qui retourne un int). Une solution ?

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    réserve fais la même chose: allouer un nouveau bloc mémoire, et copier dedans.
    En interne, que ce soit un push_back ou reserve, il y a probablement appel à realloc().

    Une piste serait de passer à une liste, qui n'a pas le problème de contiguité, mais possède un surcout par élément (les deux pointeurs).

    Dans ton code, tu n'utilises que les éléments 4 et 19, est-ce réel ou est-ce seulement pour simplifier le code?
    Car si c'est le vrai fonctionnement, il est inutile de stocker les éléments suivants (voire même de les lire)

  6. #6
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2013
    Messages : 41
    Par défaut
    Citation Envoyé par leternel Voir le message
    réserve fais la même chose: allouer un nouveau bloc mémoire, et copier dedans.
    En interne, que ce soit un push_back ou reserve, il y a probablement appel à realloc().

    Une piste serait de passer à une liste, qui n'a pas le problème de contiguité, mais possède un surcout par élément (les deux pointeurs).

    Dans ton code, tu n'utilises que les éléments 4 et 19, est-ce réel ou est-ce seulement pour simplifier le code?
    Car si c'est le vrai fonctionnement, il est inutile de stocker les éléments suivants (voire même de les lire)
    C'est par simplification en ce qui concerne le stockage de 4 et 19. J'ai également essayé de passer par une liste : même soucis. Je pense revenir aux vecteurs, parce que la fonction .at() c'est quand même bien pratique.

    J'ai vérifié un peu l'état de ma mémoire, et a priori c'est plus un problème de swap que de code. Faut donc que j'augmente la taille de mon swap (je pense que 8go ça ira). En revanche, je cherche un moyen pour faire en sorte à ce que mon programme se coupe automatiquement à genre 95% d'utilisation du swap, juste histoire d'éviter de faire subir à ma pauvre machine un crash douloureux. C'est mieux que je crée moi même l'arrêt du programme via un bon gros exit() quoi.

    Une idée de comment je peux faire ça (a coup de conditionnelles si possible) ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Access 2003] Macro qui fait planter Access
    Par nuriel2 dans le forum Access
    Réponses: 5
    Dernier message: 10/05/2006, 14h00
  2. Supprimer une crontab qui fait planter le server
    Par osmoze dans le forum Administration système
    Réponses: 5
    Dernier message: 31/03/2006, 15h42
  3. 56k qui fait planter le PC
    Par Spack dans le forum Périphériques
    Réponses: 4
    Dernier message: 03/10/2005, 19h35
  4. probleme de requette qui fait planter powergres
    Par fehmitn dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 15/09/2004, 18h48
  5. Réponses: 12
    Dernier message: 16/03/2004, 14h21

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo