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 :

Problème mémoire, suite de concaténations (strcat)


Sujet :

Langage C++

  1. #1
    Membre régulier
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2009
    Messages : 212
    Points : 93
    Points
    93
    Par défaut Problème mémoire, suite de concaténations (strcat)
    Bonjour,

    Je suis sous Ubuntu et je travaille avec CodeBlocks. Je suis face à un problème, je veux concaténer le nom de mon dossier puis celui de mon fichier. Pour ce faire, j'utilise strcat deux fois. La première mon_dossier suivie de /; et la seconde mon_premier_strcat suivie de mon_fichier. Mais là j'ai une belle erreur (pour le second) :

    ****glibc detected *** mon_chemin : free():invalid next size(): 0*00000000010e5460***
    Et là je pleure parce que c'est un problème de mémoire, je vous mets mon code et j'explique ensuite tout ce que j'ai pu entreprendre :

    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
     
        path p ("./result_dicom");
        nameFile* files;
        files = new nameFile(p);
     
        // SECONDE SOLUTION
        /*char* test;
        int size = strlen(strcat(const_cast<char*>(p.c_str()),"/"))*sizeof(char);
        test = (char*) malloc(size);
        test = strcat(const_cast<char*>(p.c_str()),"/");
     
        char* test2;
        int size2 = strlen(strcat(test,const_cast<char*>(files->getV()[0].c_str())))*sizeof(char);
        test2 = (char*) malloc(size2);
        test2 = strcat(test,const_cast<char*>(files->getV()[0].c_str()));
        cout<<test2<<endl;
        free(test);
        free(test2);*/
     
     
        //PREMIERE SOLUTION
        char* test = new char;
        test = strcat(const_cast<char*>(p.c_str()),"/");
        //cout<<test<<endl;
     
        char* test2 = new char[sizeof(test)];
        test2 = strcat(test,const_cast<char*>(files->getV()[0].c_str()));
        //cout<<test2<<endl;
     
        delete(test);
        delete(test2);
    la première solution fut de rester sur du cpp et donc d'utiliser les new. Tout ce qui est test, je n'ai aucun soucie, les test2 ça se gâte. J'ai essayé new char seul, avec ce que vous voyer plus haut, avec un nombre en dur ect rien n'y fait j'ai toujours l'erreur mentionné en haut. Si j'enlève l'allocation mémoire (même si c'est mal), l'erreur est exactement la même. Toutefois si j'affiche test2, j'ai bien ce que je souhaite dedans.

    Me semblant avoir fait le tour, et n'étant pas une pro du cpp, je suis revenue sur du c (même si c'est le mal quand on est en cpp). Et là toujours la même erreur avec le code du haut ....

    Et je vous avoue que je n'ai plus trop d'idée ^^' Après il est bien possible que ma méthode de double concaténation ne soit pas la bonne. Quelques soit vos suggestions ou idées je suis preneuse en tout cas

    Merci pour votre lecture

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Ce que tu fais est horrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrible.

    1/ pourquoi est-ce que tu alloue un char pour ensuite complètement faire disparaître le pointeur obtenu ? Du coup, lorsque tu essaie de faire un delete sur test, c'est en fait la chaine contenue dans l'objet path que tu détruit. Idem pour test2.

    1.1/ sizeof(test) ne fait pas tu tout ce que tu penses.
    1.2/

    2/ pourquoi diable est-ce que tu essaie de stocker une chaine concaténée à l'intérieur d'un objet ? Le fait que c_str() renvoie un const char* (contenu constant, pointeur variable) ne te met pas la puce à l'oreille ?

    3/ pourquoi diable est-ce que tu utilises strcat ? vu l'opération que tu demande, il serait plus sage d'utiliser std::string, non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    std::string prefix, file, result;
     
    prefix = "/";
    file = "toto";
    result = prefix + toto;
    4/ Ce que fait ton code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    test <-- zone mémoire de 1 caractère
    test <-- p.c_str() <-- p.c_str() + "/"
    // a ce state, la zone mémoire de 1 char est perdue, 
    // et le strcat peut planter parce que tu ne sais
    // pas ce que p.c_str() fait, et que rien ne te dit que tu 
    // as la place pour rajouter un caractère '/'. Si ça 
    // marche, c'est un coup de chance.
    libération de test = p.c_str()
    destruction de p
      destruction de p.c_str() // DOUBLE FREE
    Idem pour test2.

    Me semblant avoir fait le tour, et n'étant pas une pro du cpp, je suis revenue sur du c (même si c'est le mal quand on est en cpp).
    Et pour cause. Ce n'est pas une position idéologique. Mixer C et C++ va sans arrêt te provoquer des erreurs de ce type. Si le path est encapsulé dans un objet, c'est probablement pour encapsuler aussi la gestion de la mémoire associée à ce path. Il doit pouvoir être initialisé avec un std::string (plus que probablement) ou doit proposer ses propres opérateurs +, +=, ... IL FAUT LES UTILISER. Sans quoi, tu ne pourras pas faire ce que tu veux.

    Je crois voir aussi une mauvaise compréhension de ce qu'est un pointeur - mais je me trompe peut-être.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre régulier
    Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2009
    Messages
    212
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

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

    Informations forums :
    Inscription : Novembre 2009
    Messages : 212
    Points : 93
    Points
    93
    Par défaut
    Ouai je suis d'acc, c'est horrible ^^ mais je n'ai pas trop chercher non plus, je suis partie dans l'esprit PERL à vrai dire.

    1) En fait à la base le pointeur ne disparaissait pas mais à force de chercher je suis allée vers des idées disons anormales et à ne pas faire, j'en suis consciente.

    1.1 pour sizeof je suis d'ac, encore une fois j'ai cherché dans les extrèmes ^^
    1.2 je ne vois pas ce que tu entends par "à l'interieur d'un objet". Sinon je suis en char* obligatoirement avec un string à la base (tordu mais pas le choix), après j'ai récup cette ligne toute faites d'un ancien projet sans trop réfléchir je l'avoue

    1.3 et strcat = esprit PERL + avec les char* j'ai essayé d'utiliser std::string au début et ça m'a vite saoulé ...

    Je vais me remettre avec std::string et je vais voir ce que ça donne ^^' Merci en tout cas

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    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 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par angioedema Voir le message
    Ouai je suis d'acc, c'est horrible ^^ mais je n'ai pas trop chercher non plus, je suis partie dans l'esprit PERL à vrai dire.
    Pourquoi ne pas tout faire en PERL à ce moment ?
    Laissons le PERL à sa place si tu comptes faire du C++..

    Citation Envoyé par angioedema Voir le message
    1) En fait à la base le pointeur ne disparaissait pas mais à force de chercher je suis allée vers des idées disons anormales et à ne pas faire, j'en suis consciente.

    1.1 pour sizeof je suis d'ac, encore une fois j'ai cherché dans les extrèmes ^^
    Les extrêmes n'exemptent pas d'un minimum de bon sens.
    Tu faisais du C ? Tu ignores que la longueur d'une chaîne c'est strlen ?

    Citation Envoyé par angioedema Voir le message
    1.2 je ne vois pas ce que tu entends par "à l'interieur d'un objet". Sinon je suis en char* obligatoirement avec un string à la base (tordu mais pas le choix), après j'ai récup cette ligne toute faites d'un ancien projet sans trop réfléchir je l'avoue
    Ca s'apelle de l'encapsulation. Et ça sert justement à camoufler l'implémentation interne qui peut être très complexe pour ne proposer qu'une interface simple à utiliser.
    Obligatoirement en char* ? Je demande à voir (ou plutôt, j'en suis strictement pas convaincu et totalement convaincu du contraire).
    Ce qu'il y a d'extraordinaire avec std::string c'est... qu'elle possède une fonction c_str

    Citation Envoyé par angioedema Voir le message
    1.3 et strcat = esprit PERL + avec les char* j'ai essayé d'utiliser std::string au début et ça m'a vite saoulé ...
    Encore une fois, laisse le PERL à sa place.
    Saoulée d'utiliser std::string ?! Pour lui préférer strcat ?!
    Ouah...
    PERL ne sait pas faire "d'addition" de chaînes ? (Pourtant la première réponse Google montre un opérateur .)
    Tous les langages de script (si quelqu'un a un contre exemple probant ?) ont cette faculté
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    myString1 = "blabla"
    myString2 = "encore du blabla"
    myString = myString1 + myString2
    Et il n'est pas rare de voir des codes comme ça sur le forum débuter C dans de très nombreuses discussions "mon code marche pas"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    const char* myString1 = "blabla";
    const char* myString2 = "encore du blabla";
    const char* myString = myString1 + myString2;
    Non vraiment, je ne vois pas du tout où se situe la difficulté quand la std fait tout le travail lourdingue de manipulation mémoire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    std::string myString1 = "blabla";
    std::string myString2 = "encore du blabla";
    std::string myString = myString1 + myString2;
    std::cout<<myString;
    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. Problème concaténation strcat
    Par jems87 dans le forum Débuter
    Réponses: 9
    Dernier message: 23/10/2009, 11h42
  2. [CR9] [VB.NET] problème mémoire
    Par prophetky dans le forum SDK
    Réponses: 1
    Dernier message: 26/05/2005, 08h36
  3. Problème mémoire
    Par charliejo dans le forum MFC
    Réponses: 8
    Dernier message: 13/04/2005, 13h45
  4. Problémes mémoire avec le bde sur des bases paradox
    Par Keke des Iles dans le forum Bases de données
    Réponses: 2
    Dernier message: 27/05/2004, 16h55
  5. Problème mémoire avec une dll par chargement dynamique
    Par widze19 dans le forum C++Builder
    Réponses: 6
    Dernier message: 15/12/2003, 13h20

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