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 :

Realloc ou taille prédéfinie ?!


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut Realloc ou taille prédéfinie ?!
    Bonjour à tous,

    dans le cadre d'un projet, j'utilise à plusieurs reprises des tableaux de chaînes de caractères, qui n'ont pas de tailles prédéfinies. Le mieux serait que leurs tailles dépendent du besoin. Mais j'hésite entre utiliser un realloc (qui pourrait etre couteux en appel systeme, etc?) ou définir une taille maximale, donc élevée (auquel cas on réserve souvent une mémoire qui ne sera pas utile)...

    Qqun saurait ce qui est le mieux à faire?!

    Merci d'avance.

    L.

  2. #2
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Salut,

    Le meilleur moyen que j'ai vu, est de doubler la taille allouée quand la taille initiale est trop petite, tout en ayant une taille de début suffisante pour les cas les plus courants.

    Taille de départ 250
    Chaine de 251 -> doubler la taille avec realloc -> 500
    Chaine de 501 -> 1000

    Etc

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    ah oui... c'est bien pensé ça

  4. #4
    Modérateur
    Avatar de ToTo13
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Janvier 2006
    Messages
    5 793
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Santé

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 793
    Par défaut
    Bonjour,


    Citation Envoyé par KiLVaiDeN
    Salut,
    Taille de départ 250
    Chaine de 251 -> doubler la taille avec realloc -> 500
    Chaine de 501 -> 1000
    Etc
    Si tu connais la taille de ta chaine et que tu fais un realloc, alors autant faire un realloc ajusté à la bonne taille !!!!!!
    Consignes aux jeunes padawans : une image vaut 1000 mots !
    - Dans ton message respecter tu dois : les règles de rédaction et du forum, prévisualiser, relire et corriger TOUTES les FAUTES (frappes, sms, d'aurteaugrafe, mettre les ACCENTS et les BALISES) => ECRIRE clairement et en Français tu DOIS.
    - Le côté obscur je sens dans le MP => Tous tes MPs je détruirai et la réponse tu n'auras si en privé tu veux que je t'enseigne.(Lis donc ceci)
    - ton poste tu dois marquer quand la bonne réponse tu as obtenu.

  5. #5
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Citation Envoyé par ToTo13
    Bonjour,




    Si tu connais la taille de ta chaine et que tu fais un realloc, alors autant faire un realloc ajusté à la bonne taille !!!!!!
    Ca me parrait évident, si c'était trop simple je ne pense pas qu'il aurait posé la question

    J'imagine qu'il parse un fichier ou autre, et qu'il génère une chaine dynamiquement, en tout cas c'est ce que j'ai imaginé..

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    he bien, c'est simple:
    j'ai besoin d'un char** tab_chaines pour un tableau de chaines.
    Mais je ne sais pas à l'avance cb je vais y ranger de chaines (mais qd je les range, je connais la taille des chaine donc pas de pb pr le malloc du tab_chaine[n]). Le pb c le malloc du tab_chaines. Si je n'ai plus assez de place il faut bien que je réalloue, donc je pense que doubler à chaque fois est une bonne idée oui...

    (au fait, je sais que c'est rare ici mais c'est "elle" )

  7. #7
    Membre Expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 868
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 868
    Par défaut
    Question : pourquoi ne sais-tu pas combien de chaines tu vas y ranger dès le départ ?

    PS : Désolé pour l'erreur, Mademoiselle

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    ben par exemple ds la cas ici présent, je liste le contenu d'un répertoire, et je place les noms de fichiers ds le tableau...
    oui bon, ici je le connais, pas initialement mais je peux faire un realloc avec le bon nombre d'element (valeur retour de scandir)
    MAIIIIIIIIS
    dans d'autres cas... je ne le connais pas:
    exemple: lister des arguments entrés par un utilisateur au clavier.

  9. #9
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    En effet, le realloc() est necessaire dans ton cas. L'idee est d'un faire le moins possible, pour des raisons de performance et de fragmentation de la memoire. C'est pourquoi doubler la taille est une bonne solution.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    merci bien..

    dernière question: une fonction qui reçoit en argument un char** tab_chaines ne peut pas modifier (ici réallouer donc) ce tab_chaines?

  11. #11
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Citation Envoyé par ellow
    merci bien..

    dernière question: une fonction qui reçoit en argument un char** tab_chaines ne peut pas modifier (ici réallouer donc) ce tab_chaines?
    Non, garde en tête que tout paramètre ne peut pas être modifié par une fonction C (du moins, ce ne sera pas visible de la fonction appelante).

    On peut modifier la valeur de la zone pointée (dans le cas de pointeurs) ou les éléments d'un tableau mais c'est tout.

    Ainsi, tu pourrais appeler un realloc sur le pointeur mais la nouvelle valeur ne serait pas prise en compte par la fonction appelante (à moins de retourner la nouvelle addresse).

    Jc

  12. #12
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Il faut lui envoyer un char ***tab - c'est un niveau d'indirection un peu eleve, il faut bien l'admettre. J'avais ecrit une fonction similaire a la tienne, et j'avais mis tous les noms de fichier a la queue-leu-leu dans un char *tab, separes par des '\0'. On bouclait sur le contenu de ce tableau a coup de strlen()... C'est moins efficace qu'un char **tab, mais on ne se perd pas dans les indirections.

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    oui, ça me parait moins lourd aussi...

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    en tt k merci pr vos réponses
    c'est rapide ici !

  15. #15
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par ellow
    oui, ça me parait moins lourd aussi...
    Le probleme, c'est que c'est moins facile d'utilisation. Pour afficher le contenu d'un repertoire, par exemple, au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    char **filename;
     
    n_files = list_directory(directory, &filename);
    if (n_files > 0)
    {
      for (i_file = 0; i_file < n_files; i_file++)
      {
        puts(filename[i_file]);
      }
    }
    on doit faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    char *filename;
     
    n_files = list_directory(directory, &filename);
    if (n_files > 0)
    {
      char *p = filename;
      for(i_file = 0; i_file < n_files; i_file++)
      {
        puts(p);
      }
      p += (strlen(p) + 1);
    }
    Mais on peut toujours cacher les details dans une fonction display_directory()...

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    moi j'utilise scandir, et y'a pas de pb pr lister ni afficher ...
    sauf que là je commence à péter à énorme cable..

    voici la part de code qui semble poser pb:


    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
          while( i < retour )
          {
             size_name = strlen( namelist[i]->d_name );
     
             if( list_file != NULL )
             {
                realloc( list_file, size_name );
                strncat( list_file, namelist[i]->d_name, size_name );
                printf("list_file=%s |\n",list_file);
             }
             else
             {
                list_file = (char*)malloc( size_name * sizeof(char) );
                strcpy( list_file, namelist[i]->d_name );
                printf("list_file=%s \n",list_file);
             }
             i++;
          }
    Avec: ist_file un char* initialisé à NULL, retour le nombre de fichiers listés dans le répertoire concerné (renvoyé par scandir), et [I]namelist->d_name le nom du fichier listé...

    MAIS! déjà j'ai un seg fault incurable (enfin, je l'espère pas) et voici ce qui s'affiche:
    (j'affiche file_list au fur et à mesure de sa construction juste pr voir ce que ça donne );

    list_file=libShell.o
    list_file=libShell.olibStack.o
    list_file=libShell.olicStack.oline.o
    list_file=libShell.olicStack.oline.oliste.o
    list_file=libShell.olicStack.oline.oliste.opile.o
    Segmentation fault

    bon alors, le segfault, je pense pvr y remédier, mais le fait que "libStack.o"se transforme en "licStack.o" là je n'vois pas c'qui peut bien spasser ..

  17. #17
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    oui bon prr le realloc c'est pe mieux: list_file = (char*)realloc( list_file, size_name ); mais ça ne change rien à rien

  18. #18
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Tu ne fais que changer la taille de ton tableau de caractere en fonction de la longueur du nouveau fichier. Il faut augmenter la taille et utiliser strncpy(), pas strncat() [afin d'include le '\0' terminal]).
    Ensuite, il faut verifier le retour de malloc() et realloc(). Dans ton exemple, si realloc() echoue, tu provoques une fuite memoire (le list_file original n'est pas libere mais sa valeur est perdue). Il faut utiliser une variable temporaire. Enfin, on ne caste pas le retour de malloc() et realloc() en C (en C++, oui).

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    40
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 40
    Par défaut
    aha! tout le problème vient de mon realloc (évidemment quand on lit mal les pages man, on ne risque pas d'aller bien loin). Je pensais que le nombre à passer à realloc était la taille du bloc qu'on rajoutait à la fin de celui déjà alloué... Bref, j'étais à coté de la plaque.

    1000 merci

Discussions similaires

  1. reallocation matrice et taille
    Par fathese dans le forum C
    Réponses: 2
    Dernier message: 30/12/2014, 14h56
  2. Réponses: 3
    Dernier message: 11/06/2012, 05h41
  3. Récupérer la largeur d'un DIV qui na pas de taille prédéfinie.
    Par deli2025 dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 10/03/2011, 17h17
  4. Modification de la taille d'un tableau 3D avec realloc
    Par Bobsleigh dans le forum Débuter
    Réponses: 8
    Dernier message: 10/11/2009, 21h01
  5. Tableau de taille non prédéfinie
    Par pythagore3_14 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 11/08/2008, 14h34

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