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

 C++ Discussion :

execution erratique si grand tableau


Sujet :

C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 6
    Points : 3
    Points
    3
    Par défaut execution erratique si grand tableau
    Bonjour,

    Quand je déclare un grand tableau de structure à 2 dimensions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct article {
     double prix;
     double quantite;
    };
     
    const int boite_nb = 100000;
    const int colis_nb = 100;
     
    article stock[boite_nb][colis_nb];
    j'ai des valeurs bizarres dans mes variables (le tableau et d'autres variables du programme).

    Je n'ai pas besoin d'allocation dynamique car je connais la taille maxi du tableau. J'ai suffisamment de RAM libre pour la taille du tableau (100000*100*8*2)

    J'oublie quelque chose ?

    Merci !

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Ton tableau n'est pas initialisé.
    Sinon, ça peut aussi venir que ton environnement limite la taille de la pile, et que tu dépasses cette limite.
    Boost ftw

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    J'initialise le tableau ensuite dans le code, avant de l'utiliser.

    Effectivement, sous Linux la pile (stack) est limitée par défaut à 8Mo par thread. La partie données (data segment) n'est pas limitée. On a ces infos par l'instruction ulimit.

    Mais le tableau n'est pas déclaré dans la pile, non ?

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Effectivement, ton tableau ne semble pas déclaré sur la pile (on n'a pas tout le code pour juger) mais cela fait un tableau de 40 Mo tout de même, joli morceau.

    Tu es sûr que tu ne peux pas t'y prendre autrement ?
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    J'ai besoin du grand tableau,

    Peux-tu m'aider à le déclarer en dynamique pour voir si ça marche mieux ?

    (C++)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct article {
     float prix;
     float quantite;
    };
     
    int taille=1000000;
     
    article stock1[taille];
     
    void *stock2 = malloc (taille*2*sizeof(float));
    Mais comment faire que stock1 et stock2 soient le même objet ?

    Je ne suis pas sûr de mon malloc...

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Je pencherais à un débordement dans une écriture du tableau (au moment de l'initialisation?) Hypothèse : un spaghetti dans les indices ?
    Reviens sur ton premier code et inspecte les fonctions qui écrivent dans le tableau.

    [EDIT]: si ta variable est une variable globale, je ne pense pas qu'il s'agisse d'un débordement de pile

  7. #7
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut, et bienvenue sur le forum

    Le deuxième code que tu fournis est un code C et non un code C++ (malloc, et le free correspondant n'est à utiliser qu'en C... en C++, on utilise new, new[] et delete ou delete[] )

    De plus, je me demande si la création d'un tableau à deux dimensions est vraiment ce qu'il te faut, et ce, pour plusieurs raisons...

    D'abord, tu pourrais te dire que, si tu prévois 100 colis de 100 000 boites, tu peux te dire que tu dois prévoir ... 100 * 100 000 articles, et donc, travailler avec un tableau à une seule dimension de... 10 000 000 d'articles, et accéder à chaque article grâce à la formule (num_coli * nombre_boite + num_boite)

    Ensuite, s'agissant d'un stock, il y aura des entrées et des sorties, et il me semble peut être dommage de prévoir 100 colis 100000 boites (d'ailleurs, ne serait-ce pas plutôt le contraire: 100 000 colis de 100 boites ) si c'est pour que tous ces colis et toutes ces boites ne soient utilisées que de manière sopradique

    Enfin, il serait peut être intéressant de maintenir une structure supplémentaire que je nommerai (je manque d'imagination) "StockItem", qui permettrait de récupérer les information concernant l'article concerné, le numéro de colis et le numéro de boites, parce qu'il faut sans doute penser à pouvoir récupérer tôt ou tard (même si c'est seulement après une panne de courent qui a duré trop longtemps pour le temps que pouvait prendre en charge le générateur) un état de stock cohérent avec l'état qu'il représentait avant le redémarrage de l'application.

    Pour toutes ces raisons, j'envisagerais bien l'utilisation des conteneurs de la STL, ou, pourquoi pas, l'un des conteneurs de la classe boost

    Tu commencerais donc par créer une structure proche de
    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
    struct StockItem
    {
        static const size_t nbBoite = 100000; // le nombre de boite par colis
        static const size_t nbColis = 100; // le nombre maximal de colis
        size_t numBoite; // l'indice de la boite en cours
        size_t numColis; // l'indice du colis en cours
        article  art; // l'article en lui-même
        /* le constructeur */
        StockItem(size_t colis,size_t boite, article const & art):
        numColis(colis),numBoite(boite), art(art)
        {
     
            /* vérification des indexes */
            if(colis<=nbColis || boite<=nbBoite)
                throw badIndex();
        }
        /* un constructeur qui ne prend pas de colis */
        StockItem(size_t colis, size_t boite):numColis(colis), numBoite(boite),
        art(0,0)
        {
        }
        size_t uniqueIndex() const // permet de récupérer un indice unique basé 
                                  // sur le numéro de colis et le numéro de boite
        {return numColis*nbBoite+numBoite;}
        /* permet la comparaison entre deux objet du stock */
        bool operator <(StockItem const& i2) const
        {return uniqueIndex() < i2.uniqueIndex();}
    };
    Et tu créerais une autre classe "Stock" (comme je l'ai dit, je manque d'imagination ) qui pourrait prendre la forme de
    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    class Strock
    {
        public:
            void addArticle(size_t colis, size_t boite, article const& art)
            {
                /* création d'un objet de stock temporaire */
                StockItem temp(colis, boite, art);
                /* on vérifie que l'objet de stock n'existe pas */
                if(arts.find(temp)!=arts.end())
                    throw ArticleExists();
                arts.insert(temp);
            }
            void removeArt(size_t colis, size_t boite)
            {
                StockItem temp(colis, boite);
                /* cherchons l'objet de stock correspondant */
                std::set<StockItem>::const_iterator it = arts.find(temp);
                /* si on l'a trouvé, on le supprime */
                if(it!=arts.end())
                    arts.erase(it);
            }
            /* récupérons l'article correspondant à un objet de stock */
            article const& findArticle(size_t colis, size_t boite) const
            {
                StockItem temp(colis, boite);
                /* cherchons l'objet de stock correspondant */
                std::set<StockItem>::const_iterator it = arts.find(temp);
                /* si on l'a trouvé, on renvoie l'article */
                if(it!=arts.end())
                    return (*it).art;
                /* sinon on lance une exception */
                throw NotFound();
            }
            /* permet de savoir si un objet de stock existe */
            bool exists(size_t colis, size_t boite) const
            {
                StockItem temp(colis, boite);
                return arts.find(colis,boite)!=arts.end();
            }
            /* on peut vider le stock */
            void clear()
            {
                 arts.clear();
            }
            /* il y a peut etre des comportements sympa à rajouter ;) */
        private:
            /* un conteneur d'objet de stock */
            std::set<StockItem> arts;
    };
    Avec cela, tu crées ton stock sous une forme proche de
    Stock stock;
    et tu peux manipule le contenu avec les les méthodes de la classe Stock, sous des formes proches de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    article l_article(3,150);
    stock.addArticle(3,10,l_article);
    stock.removeArt(15,200);
    if(stock.exists(96,97))
    {
        /* ce qu'il faut faire */
    }
    /*...*/
    et, le jour où le patron achètera un plus grand hangars, il "suffira" de remplacer les valeur de nbColis et nbBoite et de recompiler pour que tout puisse recommencer de plus belle
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Merci à tous pour vos contributions.

    Le stock d'items, c'était juste un exemple fictif.

    En fait, la déclaration, l'initialisation et l'utilisation du tableau marche bien, cf. code de test plus bas.

    Le fonctionnement erratique venait d'un 2ème thread qui faisait appel au même moment aux fonctions qui lisent/écrivent dans le tableau (fonctions de conversion, etc.).


    Test d'un grand tableau de structure (12Mo):

    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
    struct item { 
     float prix_1;
     float prix_2;
     float prix_3;
    };
     
    const unsigned int boite_nb=10000;
    const unsigned int carton_nb=1000;
     
    item stock[boite_nb][carton_nb];//size=12Mo
     
    #include <iostream>
     
    using namespace std;
     
    int main()
    {
       //remplissage du tableau
       unsigned int i,j;
       for(i=0;i<boite_nb;i++) for(j=0;j<carton_nb;j++){
        stock[i][j].prix_1=i+j;
        stock[i][j].prix_2=i-j;
        stock[i][j].prix_3=i*j;
       }
       //affichage de la taille du tableau
       cout << sizeof(stock) << endl;
       //test du tableau
       bool error=false;
       for(i=0;i<boite_nb;i++) for(j=0;j<carton_nb;j++){
        if(stock[i][j].prix_1!=i+j) error=true;
        if(stock[i][j].prix_2!=i-j) error=true;
        if(stock[i][j].prix_3!=i*j) error=true;
       }
       if(error) cout<<"error"<<endl;else cout<<"ok"<<endl;
       return 0;
    }

  9. #9
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Mais il n'empêche que tu devrais essayer de te diriger vers une optique plus "Orientée Objet" de ton problème...

    Le fait est que l'apporche orientée objet te permettra de séparer bien plus clairement les différentes responsabilités, et donc d'arriver à quelque chose de bien plus costaud du point de vue de l'utilisation.

    De plus, et quoi qu'il en soit, la décision d'utiliser un tableau à deux dimensions est très largement discutable

    Il n'est pas exclu que la classe std::set puisse ne pas être la mieux adaptée à ton problème, mais, tu devrais surement pouvoir trouver un conteneur qui rencontre tes besoins en te basant sur cette entrée de la fAQ.

    Et, si aucun ne te semble particulièrement adapté, tu peux toujours te tourner vers boost, qui présente quelques trucs sympa
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. grand tableau dans un petit div
    Par zais_ethael dans le forum Balisage (X)HTML et validation W3C
    Réponses: 5
    Dernier message: 24/03/2006, 14h12
  2. Question l'utilisation d'un grand tableau en JS
    Par steelidol dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 02/03/2006, 21h01
  3. Charger un grand tableau de données
    Par benj63 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 24/02/2006, 17h21
  4. decalage à gauche sur une tres grand tableau de char
    Par petitours dans le forum C++Builder
    Réponses: 10
    Dernier message: 14/07/2005, 22h40
  5. Déclarer un (très) grand tableau?
    Par Cheos dans le forum C++
    Réponses: 8
    Dernier message: 17/02/2005, 17h43

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