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 :

probleme d'allocation de texte


Sujet :

C

  1. #1
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut probleme d'allocation de texte
    Bonjour a tous.
    J'ai déjà pas mal utilisé les fonctions d'allocations, malloc, calloc et free. Par contre j'ai jamais utilisé realloc mais logiquement on doit pouvoir s'en sortir avec un free et un malloc non ?

    En tout cas, j'ai un probleme dans mon code, je comprends vraiment pas, je marque deux fois la meme chose, juste que la deuxieme fois je passe par une fonction, et là j'ai un gros soucis.

    Le code C est en piece jointe.

    Le resultat a la console donne :
    stralloc: "un premier texte"
    stralloc: "un texte modifie manuellement"
    stralloc: "un premier texte"
    realloc: ""
    Merci de votre aide

    Edit de gruik : je copie colle car le code est pas long
    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
    50
    51
    #include<stdio.h>
    #include<stdlib.h>
     
    char * stralloc (const char * str)
    {
    	int i,n_char;
    	char * s;
    	for(n_char=0;str[n_char] != '\0';n_char++);
    	s= malloc((n_char+1)*sizeof(char));
    	for(i=0;i<n_char;i++)
    		s[i] = str[i];
    	s[n_char]='\0';
    	return s;
    }
     
    void strrealloc (char * str_dest, const char * str_src)
    {
    	if(str_dest != NULL)
    	{
    		free(str_dest);
    		str_dest = NULL;
    	}	
    	str_dest=stralloc(str_src);	
    }
     
    int main(void)
    {
    	char * str = NULL;
     
    	str = stralloc ("un premier texte");
    	printf("stralloc: \"%s\"\n",str);
     
    	if(str != NULL)
    	{
    		free(str);
    		str=NULL;
    	}
    	str=stralloc("un texte modifie manuellement");
    	printf("stralloc: \"%s\"\n",str);
     
    	free(str);
    	str = NULL;
     
    	str = stralloc ("un premier texte");
    	printf("stralloc: \"%s\"\n",str);
    	strrealloc(str,"texte modifier avec realloc");
    	printf("realloc: \"%s\"\n",str);
     
     
    	return EXIT_SUCCESS;
    }
    Fichiers attachés Fichiers attachés
    • Type de fichier : c text.c (868 octets, 80 affichages)

  2. #2
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Salut,

    C'est simplement qu'après ton strrealloc, le pointeur str lui meme n'est pas modifié, il pointe toujours sur l'ancienne zone où yavait la chaine, zone qui n'est plus valide après le free.

    Sinon, ton stralloc() peut être remplacé par la fonction POSIX strdup(). Si tu veux rester en C ANSI, c'est aussi implementable de façon plus optimale avec un strlen+malloc+memcpy

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    d'autant plus que

    • primo c'est plus rapide
    • secondo, le code ci-dessus ne teste pas pour les allocations échouées..

  4. #4
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut
    Merci a vous !
    C'est etrange mais en remplaçant mon ancienne fonction stralloc par strdup() dans mon strrealloc, ca fonctionne :
    [EDIT : non autant pour moi ça fonctionne toujours pas]

    En revanche j'ai une erreur :
    text.c:20: attention : incompatible implicit declaration of built-in function ‘strdup’
    juste pour ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        char * str = NULL;    
        str = strdup ("un premier texte");
    C'est bizarre, pourtant au niveau des types il me semble pas y avoir de soucis :
    char *strdup (const char *s);

    PS: sinon pour mon strrealloc, comment je pourrais resoudre mon probleme ? L'idee c'est de pouvoir modifier un texte a l'appel de cette fonction quelque soit sa taille (taille raisonnable tout de meme).


    EDIT :

    Le moyen que j'ai trouve est de faire ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    char *  strrealloc (char * str_dest, const char * str_src)
    {
    	if(str_dest != NULL)
    	{
    		free(str_dest);
    		str_dest = NULL;
    	}	
    	return str_strdup(str_src);	
    }
    C'est pas très propre.
    Je devrai peut-etre utiliser realloc finalement non ?
    Ou bien je fais un pointeur de pointeur et je passe l'adresse de mon char* à strrealloc.

    Dans ce cas je pourrais faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void  strrealloc (char ** str_dest, const char * str_src)
    {
    	if(*str_dest != NULL)
    	{
    		free(*str_dest);
    		*str_dest = NULL;
    	}	
    	*str_dest = str_strdup(str_src);	
    }
    Mais je crois que c'est encore moins propre
    Vos avis m'interessent, merci

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    déjà ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    	if(str_dest != NULL)
    	{
    		free(str_dest);
    		str_dest = NULL;
    	}
    ne peut pas marcher, car str_dest n'est pas modifiable (donc str_dest=NULL est faux).

  6. #6
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut
    Mmh oui en effet, merci de la remarque. Grace a toi, j'ai trouvé un probleme dans mon projet Je vais revoir toute mes fonctions de free. (auquel je passais directement une structure au lieu de passer par les pointeurs).

    J'aurai une question a ce propos : Existe t-il un moyen pour verifier que le free a bien fait son travail ?

    Finalement, je vais rester sur ma dernière fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void  strrealloc (char ** str_dest, const char * str_src)
    {
    	if(*str_dest != NULL)
    	{
    		free(*str_dest);
    		*str_dest = NULL;
    	}	
    	*str_dest = str_strdup(str_src);	
    }
    Je crois qu'elle fonctionne.

  7. #7
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    je trouve cette version
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *  strrealloc (char * str_dest, const char * str_src);
    la mieux, car ça correspond au prototype de realloc, enfin c'est un detail

    Sinon pour strdup() non déclaré, c'est soit que tu n'as pas inclus <string.h>, soit que tu specifies un certain standard à ton compilateur (qui interdit les foncontionnalités non ANSI/ISO)

  8. #8
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut
    Ok oui j'avais remarqué qu'elle ressemblais a realloc
    Après les deux versions c'est une question de gout, la version similaire a realloc est plus général mais fait doublon pour l'utilisation que j'en fais.
    Bref, merci de votre aide a tous.

    A propos des free(). J'ai un peu du mal a me rendre compte de certaines choses.

    Est-ce que vous etes d'accord avec moi pour dire que ici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void free_image (struct IMAGE * tmp)
    {
    	if(tmp->link != NULL)
    	{	free(tmp->link); // tmp->link est de type (char *)
    		tmp->link=NULL;		
    	}
    }
    le free fonctionne.

    mais pas ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void free_image (struct IMAGE tmp)
    {
    	if(tmp.link != NULL)
    	{	free(tmp.link); // tmp.link est de type (char *)
    		tmp.link=NULL;		
    	}
    }
    ?

  9. #9
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Non, c'est la meme chose

    Edit : je parle du free en lui meme biensur

  10. #10
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut
    Mmh d'accord.
    En revanche si je libere tmp a la fin, seule le premier free(tmp) va vraiment le liberer ?

  11. #11
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Bein tu peux pas appeler free sur une variable locale, et dans le 2eme cas, tmp est une variable locale, donc ça marcherait pas.

    Mais je pense que la vraie question, par rapport à ta précédente, c'était "est ce que je peux appeler 2 fois
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void free_image (struct IMAGE tmp);
    "?
    T'as du constater qu'il y avait un problème et la réponse est plutot straightforward

  12. #12
    Membre du Club
    Inscrit en
    Février 2009
    Messages
    9
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 9
    Par défaut
    D'ac ! Merci beaucoup a toi, j'y vois déjà plus clair.

    Connaitrez-vous un moyen pour savoir si un free a bien lieu, c'est a dire si il y a réellement libération de l'allocation mémoire ?
    Dois-je utiliser un débuggeur? Si oui, j'espère qu'il existe de bons débuggeur, le seul qu'on nous a fait utilisé a l'iut, c'est ddd et c'est pas très simple en plus j'ai pas réussi a le faire fonctionner quand on a plusieurs fichiers.
    J'utilise Geany comme IDE mais il fait pas débuggeur


    Autant pour moi, j'ai trouvé ma réponse sur wikipedia :
    http://fr.wikipedia.org/wiki/Malloc en bas de page

  13. #13
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Pour le debug mémoire Valgrind est très bien
    Pour les IDE, tu peux poser ta question dans la section adequate

  14. #14
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 157
    Billets dans le blog
    151
    Par défaut
    Pour le free(), il n'y a pas moyen de verifier s'il a bien fait son travail ou pas. Il n'a pas de valeur de retour, et ne met par à NULL lui même le pointeur.

    Mais dans la logique, free() ne peut planter...

    De plus le meilleur code que l'on puisse faire dans la séquence de désalocation est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    free(ptr);
    ptr = NULL;
    Car le free() de NULL ne fait rien ( la documentation qui le dit , et d'autres membres du forums )
    Donc pas besoin de testé si la valeur qu'on passe est égale à NULL ou pas.
    Et après une fois qu'on a fait le free() on met à NULL pour éviter de désallouer un truc que l'on a déjà désallouer ( qui provoque un comportement inconnu ( souvent un crash ).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  15. #15
    Membre Expert
    Avatar de Gruik
    Profil pro
    Développeur Web
    Inscrit en
    Juillet 2003
    Messages
    1 566
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Juillet 2003
    Messages : 1 566
    Par défaut
    Le problème de pacyang c'était qu'il mettait à bien à NULL son pointeur après free et pourtant il y avait un problème. C'est simplement qu'il le faisait sur une copie de son pointeur car la structure le contenant était copiée.
    Je parle de ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void free_image (struct IMAGE tmp);
    Donc il avait toujours un pointeur qui pointait encore sur la zone libérée

  16. #16
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    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 398
    Par défaut
    Citation Envoyé par Gruik Voir le message
    je trouve cette version
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    char *  strrealloc (char * str_dest, const char * str_src);
    la mieux, car ça correspond au prototype de realloc, enfin c'est un detail
    Justement, realloc() n'est pas du tout pratique à utiliser, avec un prototype pareil.
    Je trouve que ceci est mieux:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int strrealloc (char ** pstr_dest, const char * str_src)
    {
    	char *tmp = stralloc(str_src);
    	if(tmp == null)
    		return -1;
     
    	free(*pstr_dest);
    	*pstr_dest = tmp;
    	return 0;
    }
    Ainsi, à l'instar de realloc(), si l'allocation échoue, la chaîne est inchangée et le pointeur n'est pas modifié.
    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.

Discussions similaires

  1. probleme d allocation avec un tableau de BYTE
    Par e1lauren dans le forum C++
    Réponses: 5
    Dernier message: 06/05/2005, 13h42
  2. Probleme pour centre du texte
    Par piff62 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 08/01/2005, 11h26
  3. [FLASH MX] Probleme de nettete du texte
    Par anksou dans le forum Flash
    Réponses: 2
    Dernier message: 04/11/2004, 10h31
  4. [FLASH MX] Probleme de scrollbar et texte dynamique
    Par Bisûnûrs dans le forum Flash
    Réponses: 6
    Dernier message: 28/06/2004, 21h12
  5. probleme d'allocation dynamique
    Par vince3320 dans le forum C
    Réponses: 10
    Dernier message: 22/04/2004, 16h27

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