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 :

Question d'allocation dynamique


Sujet :

C

  1. #1
    Membre émérite
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Par défaut Question d'allocation dynamique
    Salut,

    je fais présentement des petits programmes du projet Euler. Beaucoup de problèmes nécessitent une conversion nombre à string. J'utilise sprintf() pour se faire. Mais voici mon problème, comment faire pour allouer exactement l'espace nécessaire à mon string? Voici ce que je fais présentement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char str[50];
    (void)sprintf(str, "%lu", x);
    Mon problème est le choix complètement arbitraire de la longueur du string. J'aimerais mieux allouer dynamiquement la taille exact. Comment faire?

    Merci.

  2. #2
    Membre confirmé Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Par défaut
    Tu pourrais peut-être récupérer les string dans un fichier txt du projet. Tu fais un scanf ou un getc ou s puis tu compte le nombre de caracter et alloue en fonction du nombre de caractères comptés...Je ne vois pas de solution alternative pour ma part.

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 309
    Par défaut
    Il ne lit pas les caractères dans un fichier, il les a dans un programme !

    Il suffit simplement de compter le nombre d'unité que tu as et de rajouter 1 pour le caractère d'échappement de ta chaîne C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inline unsigned countDigits(unsigned nombre)
    {
        int i = 0;
        while(nombre != 0) nombre /= 10, i++;
        return i;
    }
    Il faut que tu ajoutes 1 au nombre retourné par cette fonction, car dans une chaîne de caractères C, il y a le caractère '\0' à la fin pour la rendre valide.

  4. #4
    Membre confirmé Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Par défaut
    Ok je ne savais pas

    En fait pour répondre à ta question, je crois que j'ai trouvé une meilleure solution !
    Je viens de lire dans un topic que lorsqu'on déclare un tableau, on peut choisir de ne pas mettre le nombre d'indice mais de lui passer tout de suite un string. Voici un exemple pris du topic :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char maChaine[] = "awezgaga";

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 309
    Par défaut
    Citation Envoyé par Jordinateur Voir le message
    Ok je ne savais pas

    En fait pour répondre à ta question, je crois que j'ai trouvé une meilleure solution !
    Je viens de lire dans un topic que lorsqu'on déclare un tableau, on peut choisir de ne pas mettre le nombre d'indice mais de lui passer tout de suite un string. Voici un exemple pris du topic :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    char maChaine[] = "awezgaga";
    ...

    Et en quoi ça va l'aider ? Il ne connaît pas la taille du nombre à priori ! Cette technique ne marche que de manière statique ! Au final, le compilateur donnera une taille fixe à ton tableau, en l'occurrence ce sera toujours 9. Tu ne peux pas préciser la taille d'un tableau pendant l'exécution, tu es obligé d'utiliser l'allocation dynamique.

  6. #6
    Membre confirmé Avatar de Jordinateur
    Profil pro
    Inscrit en
    Février 2007
    Messages
    119
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 119
    Par défaut
    Ba il n'a besoin d'enregistrer qu'une seule chaine dans son exemple

  7. #7
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par PsychoH13 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    inline unsigned countDigits(unsigned nombre)
    {
        int i = 0;
        while(nombre != 0) nombre /= 10, i++;
        return i;
    }
    Attention, le mot-clé inline est uniquement disponible en C99 or, beaucoup n'utilisent pas encore cette norme et d'ailleurs la plupart des compilateurs ne compilent pas par défaut en C99 !
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  8. #8
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Par défaut
    Citation Envoyé par Jordinateur Voir le message
    Ba il n'a besoin d'enregistrer qu'une seule chaine dans son exemple
    Certes mais dans son cas, il s'agit d'une chaîne à longueur variable durant l'exécution me semble-t-il donc, ce que tu proposes ne peut l'aider en aucun cas car ceci permet de définir une chaîne statique (déclaration + initialisation) donc lors de la compilation uniquement.
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  9. #9
    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 : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par GnuVince Voir le message
    Mon problème est le choix complètement arbitraire de la longueur du string. J'aimerais mieux allouer dynamiquement la taille exact. Comment faire?
    Si ton compilateur implemente C99 et en particulier snprintf(), tu peux faire un appel a snprintf() avec une taille du buffer destination nulle et recuperer la valeur de retour de ce snprintf() qui est la taille qu'aurait eu la chaine (sans compter le \0 final) si la taille de la destination avait ete suffisament importante puis allouer le buffer destination (en pensant au +1 pour le \0) et refaire un snprintf() avec la taille allouee.

  10. #10
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Attention, le mot-clé inline est uniquement disponible en C99 or, beaucoup n'utilisent pas encore cette norme et d'ailleurs la plupart des compilateurs ne compilent pas par défaut en C99 !
    Heureusement, ce mot clé est disponible sous forme d'extension sous gcc et visual c++.

  11. #11
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Par défaut
    Si ton prog nécessite beaucoup de conversions consécutives et dans un même contexte (même thread), je pense que cela serait plus judicieux de garder un buffer alloué soit statiquement soit dynamiquement mais 1 seule fois car sinon c'est du gaspillage de temps d'alloué X fois un bloc entre 1 et quelques dizaines d'octets !!!!!

    Et a moins que tu bosses sur un système embarqué où du ne dispose que quelques ko de mémoire, cela ne sert sert à rien de chipoter pour quelques octets ! surtout si c'est ppasser son temps à allouer et à désallouer ces quelques octets....
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  12. #12
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Typiquement avant que snprintf() ne soit disponible (sachant que M$ a honteusement décidé de ne pas l'implémenter), on utilise une valeur arbitraire pour la taille d'un entier.

    Notamment, une macro comme la BIG_ENOUGH que j'ai vu sur ce forum:
    http://www.developpez.net/forums/sho...d.php?t=381525
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  13. #13
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Typiquement avant que snprintf() ne soit disponible (sachant que M$ a honteusement décidé de ne pas l'implémenter), on utilise une valeur arbitraire pour la taille d'un entier.
    http://msdn2.microsoft.com/en-us/lib...93(VS.80).aspx

  14. #14
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Cette fonction ne correspond PAS au snprintf() standard C99.
    • Elle ne met pas de caractère nul si le buffer est trop petit
    • Elle retourne une valeur négative si le buffer est trop petit.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #15
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Ah oui effectivement j'aurai mieux fait de me taire, parcontre pour ceux qui ne cherchent pas la portabilité il y a la lib strsafe.lib... (cf MSDN).
    Cordialement.

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 392
    Par défaut
    Elle ne retourne pas non plus la taille nécessaire.
    Mais côté microsoft, leur fonction _scprintf() le fait.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  17. #17
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par GnuVince Voir le message
    comment faire pour allouer exactement l'espace nécessaire à mon string? Voici ce que je fais présentement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char str[50];
    (void)sprintf(str, "%lu", x);
    Mon problème est le choix complètement arbitraire de la longueur du string. J'aimerais mieux allouer dynamiquement la taille exact. Comment faire?
    Ca n'a pas vraiment d'importance d'allouer un peu plus que nécessaire.

    Cependant, il existe une formule qui m'a été donnée par Eric Sosman (Décimal) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /* (c) Eric Sosman 2001 */
    #define BIG_ENOUGH (1 + (sizeof(long) * CHAR_BIT + 2) / 3 + 1)

Discussions similaires

  1. [malloc] questions sur l'allocation dynamique
    Par dahtah dans le forum POSIX
    Réponses: 4
    Dernier message: 21/10/2011, 01h24
  2. question sur l'allocation dynamique
    Par velociraptor5679 dans le forum C++
    Réponses: 12
    Dernier message: 29/04/2006, 23h41
  3. Question sur les problèmes d'allocation dynamique
    Par slylafone dans le forum C++
    Réponses: 23
    Dernier message: 25/10/2004, 14h18
  4. Allocation dynamique de mémoire en asm
    Par narmataru dans le forum Assembleur
    Réponses: 7
    Dernier message: 17/12/2002, 22h31
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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