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 :

Problème décrémentation -- avec pointeur


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Points : 5
    Points
    5
    Par défaut Problème décrémentation -- avec pointeur
    Bonjour,

    J'ai un problème avec ce code :

    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
     
    //Je crée une chaîne de caractères pouvant en contenir 65538
    char *Line=new char[65538];
    if(Line!=0)
    {
         //Je lis une ligne dans un fichier et je la stocke dans la chaîne de caractères
         fgets(Line,65538,hConfigurationFile);
         //Je crée une variable qui va contenir la longueur de la chaîne de caractères
         int *LineLen=new int;
         if(LineLen!=0)
         {
              *LineLen=strlen(Line);
              //Si le dernier caractère est un caractère de nouvelle ligne ou si le nombre de caractères dépasse 65536
              if(Line[*LineLen-1]=='\n' || *LineLen>65536)
              {
                   //J'efface le dernier caractère
                   Line[*LineLen]=0;
                   //Je décrémente la variable qui contient la longueur de la chaîne de caractères
                   *--LineLen;
              }
              delete LineLen;
         }
         delete[] Line;
    }
    Le problème est qu'après la décrémentation de la variable LineLen celle-ci contient une valeur erronée.

    A l'instant LineLen est égal à 11 et après la décrémentation était égal à 17.

    D'avance merci de votre aide.

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    il faut se calmer sur l'allocation dynamique.

    Pour le reste, les opérateurs ont une précédence qui détermine leur priorité.
    Et il se trouve que -- est réalisé avant *.
    Donc *--lineLen- décrémente le pointeur, soit la zone pointée
    - pointe du coup sur une zone invalide
    - l'opérateur * qui prend la valeur de cette zone ne sert à rien
    Mais l'allocation dynamique ne sert à rien dans tes 2 cas.

    http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B

    ps: std::string, std::istream
    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 éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 611
    Points
    30 611
    Par défaut
    Salut:

    Je rejoins Bousk, mais je vais meme encore plus loin : il n'y a strictement aucune raison de recourrir à l'allocation dynamique de la mémire, et tu pourrais, de plus, te simplifier énormément la vie en travaillant dans une optique C++ et non dans une optique C

    Ton code pourrait devenir quelque chose comme :
    std::ifsream ifs("fichier.txt")
    std::string configLine;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while(std::getline(configLine , ifs))
    {
        /* si on passe ici, on est sur
         * 
         * 1- qu'une ligne non vide a bel et bien été lue
         * 2- qu'on s'est arrêté au retour à la ligne
         */
    }
    Avoue que c'est quand meme plus simple, non
    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

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    struct Rule
    {
         bool InputAllowed;
         bool OutputAllowed;
         bool Redirect;
         char RedirectIpv4Addr[16];
         int RedirectPort;
    };
     
    Rule *Rules=new Rule[65535];
    ça va faire un peu beaucoup de mémoire utilisée si j'alloue un tableau statique de 65535 structures.

    Et puis je vais devoir parcourir ce tableau complètement et le plus rapidement possible alors il vaut mieux que j'utilise un tableau dynamique.

    Je me suis penché sur l'allocation dynamique seulement hier et aujourd'hui et maintenant que je comprend l'utilité des pointeurs et de l'allocation dynamique je préfère l'utiliser partout quitte à avoir plus de lignes de code.

    Je sais que les chances de tomber sur un système ne disposant plus que de 1Ko de mémoire disponible sont très faibles et que déclarer des pointeurs à tout bout de champ peut s’avérer long et pas très utile mais je trouve que bien contrôler sa consommation de mémoire est important.

    J'aime bien désallouer les variables que je n'utilise plus.

  5. #5
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par tasna Voir le message
    Je sais que les chances de tomber sur un système ne disposant plus que de 1Ko de mémoire disponible sont très faibles et que déclarer des pointeurs à tout bout de champ peut s’avérer long et pas très utile mais je trouve que bien contrôler sa consommation de mémoire est important.
    Ah! Et en quoi contrôles-tu mieux ta consommation de la sorte qu'en utilisant un tableau statique, un std::vector ou une std::string (pour l'exemple initial) avec un scope correctement géré ?

    Par contre ainsi tu vas vers du code délicat à maintenir et probablement moins robuste.

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Bah si je me remets à utiliser que des tableaux et variables statiques je ne vais pas pouvoir les désallouer quand j'en aurais plus besoin.

    C'est vrai qu'utiliser un pointeur pour une variable qu'on va juste incrémenter à un certain moment puis désallouer n'est pas très utile au vu de sa consommation de mémoire mais si on faisait tous ça on en gagnerait des Mo.

    Mais je me suis vraiment intéressé à l'allocation dynamique il y a seulement un jour et là je suis surement atteint de l'effet "J'ai appris quelque chose d'utile alors je l'utilise partout."

    Je crois que je vais utiliser l'allocation dynamique pour les longues chaînes de caractères de 8192 octets et plus ainsi que les tableaux de structures ou de sockets.

  7. #7
    Responsable Qt & Livres


    Avatar de dourouc05
    Homme Profil pro
    Ingénieur de recherche
    Inscrit en
    Août 2008
    Messages
    26 609
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur de recherche
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2008
    Messages : 26 609
    Points : 188 580
    Points
    188 580
    Par défaut
    Citation Envoyé par tasna Voir le message
    Bah si je me remets à utiliser que des tableaux et variables statiques je ne vais pas pouvoir les désallouer quand j'en aurais plus besoin.
    Non, c'est vrai, ce sera fait automatiquement en sortie du scope, il n'y a plus de risque d'oublier un free() ou un delete quelque part (même si tu aimes gérer ça, c'est une mauvaise pratique, tu le comprendras quand tu auras des applications bien plus lourdes que ça). Si tu veux vraiment en contrôler l'existence à l'instruction près, tu peux toujours utiliser un nouveau bloc d'instructions.

    Le tout n'est pas de bien aimer, de vouloir économiser le moindre octet : si, dans deux mois, tu reviens sur ton bout de code, que vas-tu te dire ? "Quel fou d'écrire ça" ou approchant. À vrai dire, ça aurait été du Perl que ça ne m'aurait pas étonné (la philosophie étant de pouvoir tout écrire de manière aussi cryptique que possible, ses adeptes disent qu'ils font comme ça des programmes très courts). Tu as été obligé de commenter chaque ligne pour te dépatouiller de ce que tu as fait, c'est déjà mauvais signe.

    Aussi, pourquoi créer un pointeur sur entier ? Grosso modo, tu doubles ta consommation mémoire ! (Voire un peu plus si tu es sur un système 64 bits.)
    Vous souhaitez participer aux rubriques Qt (tutoriels, FAQ, traductions) ou HPC ? Contactez-moi par MP.

    Créer des applications graphiques en Python avec PyQt5
    Créer des applications avec Qt 5.

    Pas de question d'ordre technique par MP !

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2011
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2011
    Messages : 21
    Points : 5
    Points
    5
    Par défaut
    Je ne commente jamais.
    Oui je sais =

    Les commentaire ne font pas partie du code actuel et la variable hConfigurationFile s'appelle même hFile. Encore moins explicite.

  9. #9
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par tasna Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    struct Rule
    {
         bool InputAllowed;
         bool OutputAllowed;
         bool Redirect;
         char RedirectIpv4Addr[16];
         int RedirectPort;
    };
     
    Rule *Rules=new Rule[65535];
    ça va faire un peu beaucoup de mémoire utilisée si j'alloue un tableau statique de 65535 structures.

    Et puis je vais devoir parcourir ce tableau complètement et le plus rapidement possible alors il vaut mieux que j'utilise un tableau dynamique.

    Je me suis penché sur l'allocation dynamique seulement hier et aujourd'hui et maintenant que je comprend l'utilité des pointeurs et de l'allocation dynamique je préfère l'utiliser partout quitte à avoir plus de lignes de code.

    Je sais que les chances de tomber sur un système ne disposant plus que de 1Ko de mémoire disponible sont très faibles et que déclarer des pointeurs à tout bout de champ peut s’avérer long et pas très utile mais je trouve que bien contrôler sa consommation de mémoire est important.

    J'aime bien désallouer les variables que je n'utilise plus.
    Mais c'est tout l'inverse que tu fais.
    - l'allocation statique et sa destruction peut être totalement contrôlée avec les scopes
    - faut-il rappeler qu'on peut créer autant de scope que l'on souhaite avec {} ?
    - les 65k structures sont de toutes façons en mémoire
    - mais en plus tu as 1 pointeur vers ses structures
    => donc tu "perds" la mémoire inutile d'un pointeur supplémentaire, pour ne pas savoir placer des {} et contrôler des sous-scopes ?
    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.

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/11/2007, 15h53
  2. Problème avec pointeur de pointeur.
    Par rutabagas dans le forum C
    Réponses: 6
    Dernier message: 18/07/2007, 19h21
  3. petit problème avec pointeurs
    Par Kerod dans le forum C
    Réponses: 12
    Dernier message: 09/12/2005, 16h48
  4. Problème de gestion de chaînes avec pointeur
    Par LorDjidane dans le forum C
    Réponses: 18
    Dernier message: 19/10/2005, 16h40

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