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 :

réécrire la méthode memset()


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut réécrire la méthode memset()
    Bonjour à tous,

    Je viens vers vous car je souhaite réécrire la méthode memset par mes propres moyens mais j'ai quelques soucis.

    Voici le lien vers l'explication de la méthode memset, si par hasard quelqu'un ne la connait pas : http://www.cplusplus.com/reference/cstring/memset/

    Le soucis étant que lorsque le 'count' est inférieur ou égale à la 'dest' cela fonctionne parfaitement mais lorsque le 'count' est supérieur, ma chaine 'dest' ne se modifie pas comme elle le devrait.

    Voici le code :

    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
     
     
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    void * monMemset(void * dest, int ch, size_t count);
     
    int main ()
    {
      char str[] = "Dupont";
      //printf("%zd\n", sizeof(str));
      monMemset(str,'A',7);
      puts(str);
      return 0;
    }
     
    void * monMemset(void * dest, int ch, size_t count){
     
        unsigned int i = 0;
        char * caracTemp = (char*)dest;
        while(*(caracTemp+i) != '\0'){
            i = i + 1;
        }
     
     
     
        if ( count > i){
            dest = malloc(count+1);
            if(dest == NULL){
                printf("ERREUR");
            }
            *((char*)dest+count+1) = '\0';
        }
        for(unsigned int i = 0; i < count; i++){
            *((char*)dest+i) = ch;
        }
        return dest;
    }
    Si quelques-un d'entre pourraient jetter un œil afin de m'aider, cela m'aiderait beaucoup car j'ai l'impression de tourner en rond

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    memset ne fait pas d'allocation mémoire normalement, est-ce que tu veux vraiment réécrire ton propre memset ou "améliorer" memset ?

    Pourquoi ne pas utiliser strlen pour mesure la taille de ta chaîne de caractère plutôt que de la parcourir toi même ?
    Si tu ne peux pas utiliser cette fonction, pourquoi ne pas créer une fonction dédiée à cela ?

    Sinon tu as trois erreurs avec ton malloc :
    - tu alloue mais tu ne libère pas le bloc mémoire anciennement pointé par dest ;
    - tu alloues mais tu ne recopie pas les octets de ton ancienne chaine de caractère (ce que tu as alloué a donc une valeur indéterminé) ;
    - si tu veux modifier la valeur de dest dans l'appelant, tu dois utiliser un pointeur de pointeur et non un pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void foo(char ** dest)
    {
          *dest = (char *)malloc(45);
    }
    foo(&maChaine);

  3. #3
    Membre éclairé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Par défaut
    une implementation de memset peut etre celle la:

    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
     
    void *monmemset(void *s, int c, int n)
    {
      char *t;
      int i;
     
      t = s; //car on ne peux pas déférencé un void*
      i = 0;
     
      for (i = 0; i < n; ++i)
      {
        t[i] = c;
      }
     
      return s;
    }

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut
    Citation Envoyé par Neckara Voir le message
    Bonjour,

    memset ne fait pas d'allocation mémoire normalement, est-ce que tu veux vraiment réécrire ton propre memset ou "améliorer" memset ?

    Pourquoi ne pas utiliser strlen pour mesure la taille de ta chaîne de caractère plutôt que de la parcourir toi même ?
    Si tu ne peux pas utiliser cette fonction, pourquoi ne pas créer une fonction dédiée à cela ?

    Sinon tu as trois erreurs avec ton malloc :
    - tu alloue mais tu ne libère pas le bloc mémoire anciennement pointé par dest ;
    - tu alloues mais tu ne recopie pas les octets de ton ancienne chaine de caractère (ce que tu as alloué a donc une valeur indéterminé) ;
    - si tu veux modifier la valeur de dest dans l'appelant, tu dois utiliser un pointeur de pointeur et non un pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void foo(char ** dest)
    {
          *dest = (char *)malloc(45);
    }
    foo(&maChaine);
    Tout d'abord merci de ta réponse.

    Tu me dis qu'il ne fait pas d'allocation mais regarde cet exemple dans lequel le 'count' est plus grand que la taille du tableau et éxécute le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    /* memset example */
    #include <stdio.h>
    #include <string.h>
     
    int main ()
    {
      char str[] = "Hello";
      memset (str,'-',7);
      puts (str);
      return 0;
    }
    Enfaite cela vient d'un exercice d'une interro que j'ai eu la semaine passée dans mon cours de théorie C/C++ et dans l'énoncé, il est indiquer que l'on ne peut utiliser, pour l'implémentation, les fonctions de la bibliothèque standard du C99 donc voila ...

    Merci pour m'avoir signaler que je ne libère pas l'ancien bloc de mémoire, j'avais complètement oublié.

    Pour ce qui est de recopier les anciens octets de ma chaine, j'avais comme logique qu'il va faire le malloc que dans le cas ou le count est strictement plus grand que la taille du tableau et donc dans ce cas je ne dois pas les réécrire vu qu'il n'y aura forcément plus de caractère de mon ancienne chaîne.

    J'espère que je me suis bien exprimé

    Citation Envoyé par EpiTouille Voir le message
    une implementation de memset peut etre celle la:

    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
     
    void *monmemset(void *s, int c, int n)
    {
      char *t;
      int i;
     
      t = s; //car on ne peux pas déférencé un void*
      i = 0;
     
      for (i = 0; i < n; ++i)
      {
        t[i] = c;
      }
     
      return s;
    }
    Cela me semble assez bref non ? et dans le cas ou le 'count' est plus grand que la taille du tableau ?

    Un grand merci pour vos réactions

  5. #5
    Membre éclairé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Par défaut
    memset n'a pas à gérer ça, c'est à l'utilisateur que utilise memset de faire attention, comme presque toutes les fonctions. Les fonctions acceptent des paramètres valides, si tu envoies n'importe quoi, c'est normal d'avoir un comportement indésirable

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2011
    Messages : 17
    Par défaut
    Oui c'est vrai je suis totalement d'accord avec toi

    Une dernière chose pour être certain, lorsque tu parles de déférencement tu souligne bien le faite que un void * doit toujours être caster ou parles-tu d'autre chose ?

  7. #7
    Membre éclairé
    Avatar de EpiTouille
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    372
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 372
    Par défaut
    je parle de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void *s;
    ...
    ...
    
    *s
    Ca n'aurait donc pas de sens d'acceder à la valeur d'un pointeur non typé. Pour cela, on le cast en char* (car un char fait 1 octet), ça nous permet donc d'acceder aux éléments contenus dans la mémoire.

  8. #8
    Membre Expert
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Par défaut
    salut,

    Citation Envoyé par Unifi Voir le message
    Cela me semble assez bref non ? et dans le cas ou le 'count' est plus grand que la taille du tableau ?
    on peut encore faire plus bref si on utilise l'arithmétique des pointeurs. Mais effectivement, si tu veux que ta version de memset fasse plus de choses que la version standard, alors il faut qu'elle ait aussi un autre nom.

  9. #9
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Pour ce qui est de recopier les anciens octets de ma chaine, j'avais comme logique qu'il va faire le malloc que dans le cas ou le count est strictement plus grand que la taille du tableau et donc dans ce cas je ne dois pas les réécrire vu qu'il n'y aura forcément plus de caractère de mon ancienne chaîne.
    Bien vu (honte à moi ).

    @EpiTouille, *mode pinaillage* un char fait un byte qui correspond plus que souvent à 8 bits (un octet).

    Sinon comme le dit mes camarades, le but de memset n'est pas de vérifier la taille alloué d'ailleurs il ne peut pas le faire.
    memset ne s'utilise pas sur des chaînes de caractères (terminée par un '\0') mais sur une chaîne/tableau de bytes (peut contenir des '\0' à l'intérieur ou non).

    D'ailleurs, même dans le cas d'une chaîne de caractère, on ne peut pas vraiment vérifier de manière sûr la taille allouée. En effet la taille allouée peut être plus grande que la taille de la chaîne de caractère.

  10. #10
    Membre Expert
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Par défaut
    Et en passant, malloc() faisant lui aussi partie de la bibliothèque standard, tu n'aurais pas non plus le droit de l'utiliser d'après l'énoncé.

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    En fait, avec ton contrôle, je me demande si tu ne cherches pas plutôt à faire un strset(), une fonction qui remplacerait tous les caractères d'une chaîne (plutôt que tous les bytes d'une zone mémoire) par la valeur désirée.

    Bien sûr, ça ne marcherait pas sur les chaînes littérales, qui sont en lecture seule. Mais ça marcherait sur ton buffer.
    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. [Méthodes]UML vs MERISE Lequel pour quoi ?
    Par Daniel258 dans le forum Méthodes
    Réponses: 5
    Dernier message: 31/03/2003, 11h49
  2. Gros Problème avec DirectShow et la méthode RELEASE
    Par Olivier Delmotte dans le forum DirectX
    Réponses: 3
    Dernier message: 10/03/2003, 18h10
  3. [Singleton] Différences avec méthodes statiques
    Par Franche dans le forum Design Patterns
    Réponses: 1
    Dernier message: 26/02/2003, 17h10
  4. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 14h26
  5. Cryptage en C selon la méthode de césat
    Par shenron dans le forum C
    Réponses: 2
    Dernier message: 31/05/2002, 08h22

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