Un malloc pollué

Voir le sujet précédent Voir le sujet suivant Aller en bas

Un malloc pollué

Message  tim le Lun 30 Juin 2008 - 10:00

Bonjour,

Le but de mon code est simple, pouvoir passer une chaine de caractères à une application tiers (flash par exemple) par le biais de sockets.
La partie réseau marche convenablement (pour l'instant).
Je tente le passage d'une chaine de caractère de type : "mesclients=serge=alain=jean", les prénoms sont récupérés via un tableau ( le tout en C )
Ce tableau de clients étant variable, la chaine est donc variable. Je me suis donc orienté vers une allocation dynamique avec un malloc et un free.
La concaténation est réussie.
Le problème est le suivant : Au début de ma chaine concaténée se trouve 3 caractères parasites du type ?3X ( Le X est variable). Cette apparition se fait dés que j'utilise le malloc de la façon suivante :
Code:
char * p = (char *)malloc(n*sizeof(char));

Auriez-vous quelques pistes sur lesquelles m'orienter ?

merci.

tim

Messages : 8
Date d'inscription : 27/06/2008

Voir le profil de l'utilisateur http://www.adherun.com

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  -ed- le Lun 30 Juin 2008 - 13:30

tim a écrit:Le but de mon code est simple, pouvoir passer une chaine de caractères à une application tiers (flash par exemple) par le biais de sockets.
OK.
La partie réseau marche convenablement (pour l'instant).
Je tente le passage d'une chaine de caractère de type : "mesclients=serge=alain=jean", les prénoms sont récupérés via un tableau ( le tout en C )
Ce tableau de clients étant variable, la chaine est donc variable. Je me suis donc orienté vers une allocation dynamique avec un malloc et un free.
Que veux tu dire par 'variable' ? La longueur de la chaine est variable ?
La concaténation est réussie.
Je ne pourrais le confirmer que quand j'aurais vu le code.

Le problème est le suivant : Au début de ma chaine concaténée se trouve 3 caractères parasites du type ?3X ( Le X est variable). Cette apparition se fait dés que j'utilise le malloc de la façon suivante :
Code:
char * p = (char *)malloc(n*sizeof(char));
ce codage, bien qu'inutilement complexe, semble correct.

Pour utiliser une forme canonique, telle que je la décris sur mon site :

Code:
char * p = malloc (n*sizeof*p);

Le problème est probablement ailleurs. Peux-tu poster le code complet, ou au moins une version réduite mais compilable qui montre le problème ?


Dernière édition par -ed- le Lun 30 Juin 2008 - 13:35, édité 1 fois (Raison : typos)

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  tim le Lun 30 Juin 2008 - 13:48

Re,

En fait le simple fait de faire un malloc,me faisait obtenir une chaine de caractères contenant encore des reliquats d'anciens programmes ( je suppose ). D'où ces 3 petits caractères que j'obtenais après un affichage de ma variable en mode console. ( je tiens à préciser que j'affichais la valeur de la variable juste après le malloc, sans faire de concaténation ou quoi que ce soit ). Finalement, après quelques recherches je me suis orienté vers la fonction memset(). Cela devrait pouvoir initialiser ma chaine à vide et ainsi virer ces quelques parasites. Je testerai ça ce soir, car mon code n'est pas sous la main.
Je pense également que votre forme canonique est plus facile à utiliser, à comprendre du moins.
Ce que je voulais dire par variable dynamique, c'était qu'elle pouvait changer de longueur selon la taille du tableau.
i.e selon le nombre de clients connectés, j'aurais eu besoin d'envoyer la chaine les listant :

"MESCLIENTS=jean=paul=rémy=max=fred"

Cette chaine peut être composée que de MESCLIENTS= s'il n'y a personne de connecté ou d'une centaines de prénoms. D'ou mon besoin de créer une malloc pour optimiser la charge du serveur.

Mais je dois avouer que je ne connais que cette solution pour gérer des chaines avec longueur variables, ce qui est fort dommage, car j'imagine que dans l'hypothèse d'une grosse charge niveau clients, le fait de faire autant de malloc va sérieusement ralentir mon serveur, même si j'effectue un free et une initialisation à NULL derrière.

tim

Messages : 8
Date d'inscription : 27/06/2008

Voir le profil de l'utilisateur http://www.adherun.com

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  tim le Lun 30 Juin 2008 - 13:55

Par exemple,

Le code ci dessous

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char  *  p  =  (char  *)malloc(12*sizeof(char));
    //memset(p,0,12);
    strcat(p," <- ma malloc");
    printf("ma variable p : %s \n",p);
    return 0;
}

m'affichait :

Code:
ma variable p : $£µ <- ma malloc

Pour y remedier,
Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char  *  p  =  (char  *)malloc(12*sizeof(char));
    memset(p,0,12);
    strcat(p," <- ma malloc");
    printf("ma variable p : %s \n",p);
    return 0;
}

ou

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main()
{
    char  *  p  =  (char  *)malloc(12*sizeof(char));
    p[0]='\0';
    strcat(p," <- ma malloc");
    printf("ma variable p : %s \n",p);
    return 0;
}
m'affiche le résultat souhaité :

Code:
ma variable p : <- ma malloc

tim

Messages : 8
Date d'inscription : 27/06/2008

Voir le profil de l'utilisateur http://www.adherun.com

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  -ed- le Lun 30 Juin 2008 - 14:15

tim a écrit:En fait le simple fait de faire un malloc,me faisait obtenir une chaine de caractères contenant encore des reliquats d'anciens programmes ( je suppose ).
C'est le comportement normal de malloc(). L'espace mémoire alloué n'est pas initialisé. C'est à l'utilisateur de le faire.
Finalement, après quelques recherches je me suis orienté vers la fonction memset(). Cela devrait pouvoir initialiser ma chaine à vide et ainsi virer ces quelques parasites. Je testerai ça ce soir, car mon code n'est pas sous la main.
C'est une possibilité, mais elle est un peu lourde. Le principe est soit de copier une chaine valide

Code:
  strcpy (p, "hello world");

soit d'initialiser la chaine à "" avant de faire un strcat() :
Code:

  strcpy (p, "");
  strcat (p, "hello");
  strcat (p, " world");
on peut aussi faire comme ceci :
Code:

  strcpy (p, "hello");
  strcat (p, " world");
Nota : on peut remplacer strcpy (p, ""); par *p = 0;

Je pense également que votre forme canonique est plus facile à utiliser, à comprendre du moins.
Ce que je voulais dire par variable dynamique, c'était qu'elle pouvait changer de longueur selon la taille du tableau.
i.e selon le nombre de clients connectés, j'aurais eu besoin d'envoyer la chaine les listant :

"MESCLIENTS=jean=paul=rémy=max=fred"

Cette chaine peut être composée que de MESCLIENTS= s'il n'y a personne de connecté ou d'une centaines de prénoms. D'ou mon besoin de créer une malloc pour optimiser la charge du serveur.
Oui, c'est un bon choix. Il faut bien faire attention à la manière dont la taille est évaluée, sinon, l'allocation n'a pas la bonne taille et le comportement est indéterminé.

Mais je dois avouer que je ne connais que cette solution pour gérer des chaines avec longueur variables, ce qui est fort dommage, car j'imagine que dans l'hypothèse d'une grosse charge niveau clients, le fait de faire autant de malloc va sérieusement ralentir mon serveur, même si j'effectue un free et une initialisation à NULL derrière.
Tout appel de fonctions a un coût. Si les performances sont critiques, on peut envisager une pré-allocation avec une taille raisonnable, un pool etc. Il faut que ça en vaille le coup, car il y a pas mal de code à implémenter et à valider pour créer un pool efficace et fiable.

En attendant, il faut réaliser du code qui fonctionne, faire des mesures et voir si il faut vraiment passer du temps à optimiser

"Premature optimization is the root of all evil"
-- Donald Knuth


Dernière édition par -ed- le Lun 30 Juin 2008 - 14:21, édité 4 fois

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  tim le Lun 30 Juin 2008 - 14:18

"Premature optimization is the root of all evil"

Effectivement, je ferais mieux de m'assurer que le bout de code marche avant de penser optimisation.

Finalement je pense opter pour

Code:
strcpy (p, "");

comme vous l'aviez proposé auparavant.

Merci pour tous ces détails.

tim

Messages : 8
Date d'inscription : 27/06/2008

Voir le profil de l'utilisateur http://www.adherun.com

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  -ed- le Lun 30 Juin 2008 - 14:22

tim a écrit:Par exemple,

Le code ci dessous
Tes essais confirment ma théorie.

-ed-
Admin
Admin

Messages : 289
Date d'inscription : 26/05/2008
Age : 60
Localisation : Paris 6eme arrondissement (75, France)

Voir le profil de l'utilisateur http://bien-programmer.fr

Revenir en haut Aller en bas

Re: Un malloc pollué

Message  Contenu sponsorisé Aujourd'hui à 21:21


Contenu sponsorisé


Revenir en haut Aller en bas

Voir le sujet précédent Voir le sujet suivant Revenir en haut


 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum