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 :

int n = *((int *)p)


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 14
    Points
    14
    Par défaut int n = *((int *)p)
    Bonjour,

    je reçois par le réseau des données, je vais avoir par exemple un entier sur 4 octets, stocké dans un buffer.

    le code suivant est-il toujours correct ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unsigned char buffer[100];
     
    /* buffer[1..4] va contenir mon entier */
     
    int n = *((int *)&buffer[1]); /* je suppose que sizeof(int) == 4, et je me fous de l'endianness, l'important n'est pas là */
    Je pense que ce n'est pas correct. A cause du fait que &buffer[1] n'est pas forcément correctement placé en mémoire pour pointer vers un int, et qu'il faut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(&n, &buffer[1], 4);
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    n = buffer[1] * ? + buffer[2] * ? + etc...

    J'ai raison ou pas ?

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Tu as sacrément intérêt à être sûr de toi (données reçues, boutisme des données reçues), mais je suppose que c'est ton problème.

    L'autre problème que tu risque d'avoir est un problème d'alignement mémoire. &buffer[1] va être une adresse impaire et suivant les machines, le déréférencement d'un pointeur impair va soit prendre du temps (génération des cycles intermédiaires pour lire une adresse non correctement alignée) soit générer une erreur sur le bus.

    Donc la solution de copie me parait la plus sûre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    memcpy(&n, &buffer[1], 4);
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    L'autre problème que tu risque d'avoir est un problème d'alignement mémoire. &buffer[1] va être une adresse impaire et suivant les machines, le déréférencement d'un pointeur impair va soit prendre du temps (génération des cycles intermédiaires pour lire une adresse non correctement alignée) soit générer une erreur sur le bus.
    C'est ce à quoi je pensais, je voulais une confirmation.

    Merci.

  4. #4
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Je te confirme un point en tout cas : sur une machine à base de processeur Sparc (Sun), ton code initial provoquera systématiquement un arrêt du programme avec un "Bus Error"...

    Sur un x86, le cast "bourrin" marchera, ainsi que sur beaucoup de processeurs. Mais il existe d'autres processeurs qui, eux, ne supporteront pas ce genre de copie non alignée.

    Le "memcpy" est garanti fonctionnel, mais le remplissage de ton entier octet par octet n'est pas forcément garanti. "memcpy" est donc fiable, même si ce n'est pas (forcément) la solution la plus rapide possible sur certains processeurs.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2009
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    le remplissage de ton entier octet par octet n'est pas forcément garanti
    Comment ça ?

  6. #6
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Points : 4 846
    Points
    4 846
    Par défaut
    Il est possible que la lecture de ton octet force une lecture "int" non alignée de par la nature de la variable de destination. Peu probable, certes, mais possible malgré tout (et donc dangereux).

    Il faudrait utiliser plusieurs casts, voire variables temporaires, pour garantir que l'affectation d'un octet vers l'entier destination se fait exclusivement via les registres, qui ne sont pas soumis aux contraintes d'alignement.

    De façon générale, les lectures non alignées devraient être limitées soit à des accès de champs de structures (gérés par le compilateur), soit à plate-formes connues pour ne PAS avoir de problèmes d'accès non-aligné... Sachant que même sur un x86, un accès non-aligné n'est de toutes façons pas une bonne idée, cela coûte plus de temps CPU qu'un accès aligné.

    Normalement, "memcpy" est prévu pour être implémenté au plus efficace, c'est à dire avec le maximum possible d'accès alignés.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

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

Discussions similaires

  1. Transformer (int année, int mois, int jour) en millisecondes
    Par Logic_613 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 24/04/2012, 11h08
  2. Réponses: 8
    Dernier message: 09/02/2007, 15h31
  3. int, unsigned int, et la fonction pow
    Par salseropom dans le forum C
    Réponses: 11
    Dernier message: 22/12/2006, 17h53
  4. comment faire marcher int random(int num);
    Par Marc_3 dans le forum C++
    Réponses: 5
    Dernier message: 21/08/2006, 08h49
  5. short int et int
    Par gaut dans le forum C
    Réponses: 3
    Dernier message: 07/02/2004, 21h06

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