Partage
  • Partager sur Facebook
  • Partager sur Twitter

sizeof(structure)

    15 janvier 2020 à 17:46:57

    Bonjour,

    j'ai un problème de la taille d'une structure ??!!

    voila l'exmple:

    #include <stdio.h>
    
    #include <stdlib.h>
    
    typedef struct Header{
    
        char b; //1 octet
    
        char m; // + 1Octet =>   2 Octet
    
        long x; // 4 6
    
        long y; //4 10
    
         long z;// 4 14
    
        long e;// 4 18
    
        long f;// 4 22
    
        long g; // 4 26 Octets
    
    }Header;
    
    int main(){
    
        int l;
        
        FILE* er=fopen("d:\image.bmp","rb");
    
        Header  *h =(Header*)malloc(sizeof(Header));
        printf("taille de la structure=%d  \n",sizeof(Header)); // la fonction sizeof return 28 au lieu de 26 ??!!!!!!!
    
        fseek(er,0,0);
    
        fread(h,sizeof(Header),1,er);
    
        fseek(er,18,0);
    
        fread(&l,4,1,er);
    
        fclose(er);
    
        return 0;
    
    }



    -
    Edité par AhmedMhamdi8 15 janvier 2020 à 20:40:47

    • Partager sur Facebook
    • Partager sur Twitter
      15 janvier 2020 à 18:13:49

      Hello,

      1) utilise le bouton </> pour poster du code

      2) oui, c'est normal d'avoir 28 plutôt que 26: le compilateur aligne x sur un multiple de 4 octets, et tu perds 2 octets entre m et x. Tu as donc un "trou" à cet endroit-là. Un début d'explication ici

      -
      Edité par edgarjacobs 15 janvier 2020 à 18:15:10

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        15 janvier 2020 à 18:22:58

        Bonjour,

        Merci de colorer votre code à l'aide du bouton Code

        Les forums d'Openclassrooms disposent d'une fonctionnalité permettant de colorer et mettre en forme les codes source afin de les rendre plus lisibles et faciles à manipuler par les intervenants. Pour cela, il faut utiliser le bouton Code de l'éditeur, choisir un des langages proposés et coller votre code dans la zone prévue. Si vous utilisez l'éditeur de messages en mode Markdown, il faut utiliser les balises <pre class="brush: cpp;">Votre code ici</pre>.

        Manque de Politesse

        Votre message ne comporte pas ou peu de formules de politesse (« Bonjour », « Merci », « Au revoir », etc.). Les règles du site exigent que chaque nouveau message comporte un minimum de politesse. Après tout, les gens qui répondent le font gratuitement, sur leur temps libre. Ils méritent bien un minimum de considération, n'est-ce pas ?

        Liens conseillés

        • Partager sur Facebook
        • Partager sur Twitter
          15 janvier 2020 à 20:52:54

          Merci beaucoup pour la réponse. J'ai bien compris le problème. Alors comment je peut faire pour lire ma structure, qui modélise l'entête d'un fichier bitmap (image bmp), en un seul coup à partir du fichier: 
          fread(h,sizeof(Header),1,er);
          • Partager sur Facebook
          • Partager sur Twitter
            15 janvier 2020 à 22:54:00

            Voici une explication

            http://fvirtman.free.fr/recueil/01_08_01_05_memalign.c.php

            Et a la fin, je parle du pragma pour désactiver l'alignement mémoire pour lire ton header de BMP d'un coup si tu veux.

            • Partager sur Facebook
            • Partager sur Twitter

            Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

              16 janvier 2020 à 7:33:32

              Si on veut  un  format de fichier et du code portable, ça va pas le faire de se reposer sur int ou long, dont la taille dépend de plein de choses.

              Sans parler de l'ordre des octets.

              • Partager sur Facebook
              • Partager sur Twitter
                16 janvier 2020 à 9:35:53

                AhmedMhamdi8 a écrit:

                Merci beaucoup pour la réponse. J'ai bien compris le problème. Alors comment je peut faire pour lire ma structure, qui modélise l'entête d'un fichier bitmap (image bmp), en un seul coup à partir du fichier: 

                fread(h,sizeof(Header),1,er);


                Il faut forcer l'alignement de la structure avec le mot clé alignas en C11 et utiliser des entiers fixes comme uint8_t, int16_t, etc. Note : ces derniers ne sont pas forcément disponibles car ils sont facultatifs dans la norme.

                Globalement, le plus simple est de lire chaque partie une à une.

                Oublie pas non plus qu'il y a l'endian à gérer donc tu devras retourner les bits si nécessaire.

                -
                Edité par markand 16 janvier 2020 à 9:46:10

                • Partager sur Facebook
                • Partager sur Twitter

                git is great because Linus did it, mercurial is better because he didn't.

                  16 janvier 2020 à 9:56:12

                  La triste vérité est qu'on ne peut pas le faire d'un coup d'un seul, à cause des problèmes de portabilité.

                  Donc pour lire :

                  • avoir un tampon (chars) de la taille qui correspond a celle de l'entete dans le fichier
                  • lire ces octets.
                  • utiliser des fonctions/expressions de conversion octets <-> entier pour remplir la structure.
                  char buffer[28];
                  
                  read(.... buffer, 28);
                  
                  struct Header h = {
                     .b = buffer[0],
                     .m = buffer[1],
                     .x = buffer[3] << 24 | buffer[2] << 16  | buffer[1] << 8 | buffer[0],
                      ...
                  };
                   

                  -
                  Edité par michelbillaud 16 janvier 2020 à 9:58:01

                  • Partager sur Facebook
                  • Partager sur Twitter
                    19 janvier 2020 à 13:54:07

                    Bonjour,

                    Il y a aussi la possibilité de se faire un petit jeu de fonctions de lecture/écriture pour 8/16/32/64 en BE/LE. Mais il reste nécessaire de lire/écrire une structure membre par membre. Pour du 32 bits non signé en LE par exemple :

                    uint32_t read_u32le(FILE* f)
                    {/*lecture u32 bits dans fichier le*/
                        uint8_t b[4];
                    
                        if(fread(b, 1, sizeof(b), f) != sizeof(b))
                            readWriteErr++;
                    
                        return 0U | b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;
                    }
                    
                    void write_u32le(uint32_t val, FILE* f)
                    {/*ecriture u32 le dans fichier*/
                        uint8_t b[4];
                    
                        b[0] = val       & 0xff;
                        b[1] = (val>>8)  & 0xff;
                        b[2] = (val>>16) & 0xff;
                        b[3] = (val>>24) & 0xff;
                    
                        if(fwrite(b, 1, sizeof(b), f) != sizeof(b))
                            readWriteErr++;
                    }


                    La relecture du fichier pour alimenter une structure ressemble alors à un truc comme ça :

                    void L_scrollTypeRead(FILE* file, CEV_ScrollText *in)
                    {
                        /*PRL*/
                    
                        if (IS_NULL(in) || IS_NULL(file))
                        {
                            readWriteErr++;
                            return;
                        }
                    
                        /*EXECUTION*/
                    
                        in->fontSize = read_u32le(file);
                        in->color.r  = read_u8(file);
                        in->color.g  = read_u8(file);
                        in->color.b  = read_u8(file);
                        in->color.a  = read_u8(file);
                        in->mode     = read_u32le(file);
                        in->space    = read_u32le(file);
                        in->speed    = read_u32le(file);
                    
                    }

                     C'est plus chiant que de faire un fread / fwrite sur la structure, mais ça évite les problèmes de padding (qui en plus mettent des données poubelles dans le fichier lors de l'écriture), les problèmes d'endianess et de taille des données. Tu imposes ainsi exactement ce qui doit être lu, comment et l'interprétation qui doit en être faite, plus aucune chance n'est laissée au hasard.

                    Si tu es intéressé, voici un lien vers le sujet qui a fait mon instruction en la matière, tu y trouveras des informations plus poussées sur le pourquoi et le comment.

                    Bonne continuation.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Bonhomme !! | Jeu de plateforme : Prototype.

                    sizeof(structure)

                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                    • Editeur
                    • Markdown