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 :

Utilisation de memset()


Sujet :

C

Vue hybride

Kr00pS Utilisation de memset() 12/02/2007, 12h02
josse95 Tu fournis à memset un... 12/02/2007, 12h14
Gruik Salux, Je vois pas de... 12/02/2007, 12h20
Emmanuel Delahaye Oui. Il faut savoir que... 12/02/2007, 12h24
Ulmo La norme IEEE te le garantie... 12/02/2007, 13h35
Copros Petite question... 15/03/2007, 15h41
Emmanuel Delahaye Je n'en connais pas. 15/03/2007, 15h56
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Octobre 2005
    Messages
    141
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations forums :
    Inscription : Octobre 2005
    Messages : 141
    Par défaut Utilisation de memset()
    Bonjour !

    memset() n'étant pas une fonction que j'utilise très souvent, je voudrais savoir si j'ai juste sur ces points :

    * La fonction de memset() est d'initialiser une variable (peu importe le type vu que c'est void). Ca marche pour tout ?
    * Il y a t'il des "contraintes" ?

    Merci.

    Kr00pS

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 349
    Par défaut
    Tu fournis à memset un pointeur sur une zone mémoire ainsi qu'une taille (en octets).
    Effectivement, memset se moque du type de données que tu manipules et ne fait aucun contrôle sur les arguments. A toi de t'assurer que tu transmets une zone mémoire valide (c'est le danger (et la puissance) du C, tu peux tout faire !)

  3. #3
    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
    Salux,

    Je vois pas de contraintes, si ce n'est que tu initialises une zone octet par octet, ce qui veut dire que tu es un peu au courant de comment sont organisées les données.

    Autre petit probleme, tu veux "initialiser" une structure qui contient des pointeurs et d'autres champs scalaires (des entiers)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct
    {
     const char * s;
     int a;
     int b;
     void * ptr;
    } mon_struct;
     
    /* ... */
    /* RAZ de mon_struct */
    memset(&mon_struct, 0, sizeof mon_struct);
    .. tu as cassé l'abstraction du NULL en disant que NULL == 0.

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Kr00pS
    Bonjour !

    memset() n'étant pas une fonction que j'utilise très souvent, je voudrais savoir si j'ai juste sur ces points :

    * La fonction de memset() est d'initialiser une variable (peu importe le type vu que c'est void). Ca marche pour tout ?
    * Il y a t'il des "contraintes" ?
    Oui. Il faut savoir que memset() est une fonction de bas niveau qui se contente de recopier bêtement le 'pattern' passé en paramètre dans tous les bytes désignés (adresse, longueur), et ce sans tenir compte du type. Par exemple, si on passe 0, et que les bytes font 8-bit, le pattern 00000000 va être recopier dans la zone désignée (all-bit-to-zero).

    A part si il s'agit de char, le comportement est indéfini.

    En effet, un tel pattern dans un variable peut correspondre à une "Trap représentation", c'est à dire une valeur interdite. Pire, si c'est un pointeur ça ne signifie pas forcément NULL et si c'est un flottant ou un double, rien ne dit que ce soit 0.0f ni 0.0.

    Le même genre de problème apparait avec memcmp(). La comparaison se fait "bit à bit" sans tenir compte ni de la structure des données ni de leur type. Si il y a des bytes de padding dans les structures, et que ceux-ci ont des valeurs différentes, la comparaison avec memcmp() ne fonctionne pas.
    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
     
    #include "ed/inc/sys.h"
    /*
    ** http://emmanuel-delahaye.developpez.com/clib.htm
    */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    struct data
    {
       char x;
       int y;
    };
     
    int main (void)
    {
       struct data a;
       struct data b;
     
       printf ("sizeof a = %u\n", (unsigned) sizeof a);
     
       memset (&a, 0, sizeof a);
       memset (&b, 0xFF, sizeof b);
     
       SYS_dump (&a, sizeof a);
       SYS_dump (&b, sizeof b);
     
       a.x = b.x = 1;               /* abus dabgereux... */
       a.y = b.y = 2;
     
       SYS_dump (&a, sizeof a);
       SYS_dump (&b, sizeof b);
     
       if (memcmp (&a, &b, sizeof a) == 0)
       {
          puts ("a == b");
       }
       else
       {
          puts ("a <> b");
       }
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    sizeof a = 8
    0022FF68 00 00 00 00 00 00 00 00                          '........'
    0022FF60 FF FF FF FF FF FF FF FF                          '........'
    0022FF68 01 00 00 00 02 00 00 00                          '........'
    0022FF60 01 FF FF FF 02 00 00 00                          '........'
    a <> b
     
    Press ENTER to continue.

  5. #5
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Pire, [si c'est un pointeur ça ne signifie pas forcément NULL et] si c'est un flottant ou un double, rien ne dit que ce soit 0.0f ni 0.0.
    La norme IEEE te le garantie pour les float et double.
    (Elle n'est pas utilisée partout, ce qui te donne raison. Mais je m'étais posé la question).

  6. #6
    Membre confirmé
    Inscrit en
    Avril 2006
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 36
    Par défaut
    Petite question complémentaire, si j'ai un tableau de flottants à initialiser à 1 (ceci afin d'éviter tout débat concernant l'équivalence entre `all-bits-to-zero' et 0.0f), y a-t-il une meilleure méthode que la bonne vieille boucle for ? Je dis "meilleure" au sens efficacité, portabilité et propreté.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    float tab[N];
    int i;
    for(i=0 ; i<N ; ++i)
    {
      tab[i] = 1.f;
    }

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par BVertut
    y a-t-il une meilleure méthode que la bonne vieille boucle for ? Je dis "meilleure" au sens efficacité, portabilité et propreté.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    float tab[N];
    int i;
    for(i=0 ; i<N ; ++i)
    {
      tab[i] = 1.f;
    }
    Je n'en connais pas.

  8. #8
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    Et celle-ci?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    float tab[N] = {1.0f};

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 26/04/2010, 16h06
  2. Utilisation de memset
    Par mister3957 dans le forum C++
    Réponses: 2
    Dernier message: 23/11/2008, 14h02
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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