Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1377 connectés 

  FORUM HardWare.fr
  Programmation
  C

  sprintf et mémoire

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

sprintf et mémoire

n°1335822
Dinan
Posté le 30-03-2006 à 20:10:18  profilanswer
 

Bonjour,
 

Code :
  1. for (i=0; i<16; i++) { // On converti la chaine MD5
  2.  sprintf (pRet, "%s%02x", pRet, digest [i]);
  3. }


 
Ceci est censez me remplir pRet d'une chaine MD5 (32 caractères).
Je lui allou donc sizeof(char)*32.
 
Le probleme c'est que je segfault et que dans pRet j'ai n'importe quoi en début de chaine.
Je pense que cela est dû à que sprintf li et écrit sur un pointeur en meme temps.
 
Quelle solution ?
 
Merci

mood
Publicité
Posté le 30-03-2006 à 20:10:18  profilanswer
 

n°1335878
skelter
Posté le 30-03-2006 à 21:04:28  profilanswer
 

Citation :

Je lui allou donc sizeof(char)*32.


 
malloc(33), en comptant le caractere nul en fin de chaine
l'allocation dynamique est vraiment nécéssaire ?
 
tu veux pas plutot faire
 

for (i=0; i<16; i++) { // On converti la chaine MD5
  sprintf (pRet + i*2, "%02x", digest [i]);
}

n°1335879
Elmoricq
Modérateur
Posté le 30-03-2006 à 21:06:41  profilanswer
 

Si pRet n'est pas initialisé au début, ça va t'écrire ce qu'il y a en mémoire jusqu'à ce que ça trouve un char à 0.
 
Ca peut mener très loin dans la mémoire... jusqu'à un segfault.
 
Et mettre à NULL pRet n'est pas une solution non plus, parce que ...printf() réagit assez mal aux pointeurs NULL :D
 
La solution est, après avoir alloué pRet, de l'initialiser avec le premier bout de ta chaîne, puis de faire ta boucle sur 16-1 itérations.
 
Autre chose : il faut lui allouer "(32 + 1) * sizeof char" à pRet, pour pouvoir y stocker le caractère \0 terminal.

n°1335894
Dinan
Posté le 30-03-2006 à 21:42:34  profilanswer
 

char *pRet = malloc(sizeof(char) * (32 + 1));
 pRet[0] = '\0';
 
avec le pRet[0] = '\0'; je n'est plus les reste de mémoire.
Mais comment se fait il qu'après un malloc, si j'affiche le contenu de la variable il ya des débris de mémoire ?
 
Et non l'allocation dynamique n'est pas nécéssaire mais si je fait char pRet[33]; comment je peut le return ?


Message édité par Dinan le 30-03-2006 à 21:45:50
n°1335897
olivthill
Posté le 30-03-2006 à 21:50:47  profilanswer
 

Je seconde Skelter. Je pense donc aussi que le malloc n'est pas nécessaire dans ce cas, et pourrait être avantageusement remplacé par une réservation sur la pile par un simple

char pRet[33];

Pour avoir juste une petite idée de la complexité qui se cache derrière un simple appel de la fonction malloc(), lire http://www-128.ibm.com/developerwo [...] /l-memory/ et plus spécifiquement les liens en bas de l'article pour des implémentations sur des environnements particuliers.
Edit : Je viens de voir la question pour le return, et il suffit allors de déclarer la variable avec le scope nécessaire, en l'occurence en dehors de la fonction pour qu'elle soit visible depuis la fonction appelante. Habituellement, c'est même la fonction appelante qui fait la réservation mémoire, et qui passe le pointeur à la fonction (comme le propose aussi Trap D).


Message édité par olivthill le 30-03-2006 à 21:55:30
n°1335899
Trap D
Posté le 30-03-2006 à 21:53:05  profilanswer
 

Tu peux passer un tableau de caractères assez grand en paramètre de ta fonction et écrire dedans, comme ça pas de problème de return.
D'autre part, sizeof(char) = 1 par définition.


Message édité par Trap D le 30-03-2006 à 22:01:55
n°1335905
skelter
Posté le 30-03-2006 à 22:05:26  profilanswer
 

et dans ce cas vu que la tailles est fixe, on peut prototyper la fonction de maniere à ce qu'elle ne recoivent que l'adresse de ce type de tableau
 

Code :
  1. void func(char (*tab)[33])
  2. {
  3. /*
  4. sizeof *tab == 33
  5. */
  6. strcpy(*tab, ...);
  7. }
  8. int main()
  9. {
  10. char tab[33];
  11. func(&tab);
  12. }

n°1335907
Dinan
Posté le 30-03-2006 à 22:07:11  profilanswer
 

Merci tous cela marche, mais pourquoi ma variable n'est pas vide après l'avoir initialisé ? (valeur aléatoire de la mémoire)

n°1335909
skelter
Posté le 30-03-2006 à 22:10:34  profilanswer
 

c'est le pointeur que tu initialise avec une adresse, pas la zone mémoire pointée
pour initiliser la zone mémoire pointée tu peux allouer avec calloc utiliser memset

n°1335913
Dinan
Posté le 30-03-2006 à 22:17:21  profilanswer
 

char SESSID[33];
SESSID[0] = '\0';
 
En faisant la mon sprintf ne déconne plus, je sait pas si c'est très propre, mais je vais opter pour cette solution.
 
Merci à vous.

mood
Publicité
Posté le 30-03-2006 à 22:17:21  profilanswer
 

n°1335918
skelter
Posté le 30-03-2006 à 22:28:15  profilanswer
 

tu peux faire directement
char SESSID[33] = "";

n°1335925
0x90
Posté le 30-03-2006 à 22:43:22  profilanswer
 
n°1335943
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-03-2006 à 23:04:18  profilanswer
 

Dinan a écrit :


Code :
  1. sprintf (pRet, "%s%02x", pRet, digest [i]);
  2. }


Je pense que cela est dû à que sprintf li et écrit sur un pointeur en meme temps.


Exactement. Il y a recouvrement, ce n'est pas permis. Il faut une variable intermédiaire.


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  sprintf et mémoire

 

Sujets relatifs
debutant: gestion de la mémoireAdresse memoire d'une constante??
Allocation mémoirePointeurs, gestion de la memoire (Pascal)
allocation de mémoire alignéeConsulter une mémoire partagée
Mémoire défaillante chez Internet Explorer !?Taille exe et utilisation memoire programme
Affichage dans la memoire videoGros et bizarre trou de mémoire...
Plus de sujets relatifs à : sprintf et mémoire


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR