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 :

Copie de nombres dans une structure générique


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Par défaut Copie de nombres dans une structure générique
    Bonjour à tous,

    J’essaie actuellement de créer une structure générique afin de stocker des données.
    J'utilise une pile pour le stockage temporaire des données ( float, int, double, ... ) puis je veux les copier dans un tableau dynamique.
    J'ai d'abord essayé de déclarer le tableau comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void* array = malloc(i*numberSize);
    Cependant, Si ce tableau dynamique est déclaré en tant que void*, j'obtient l'erreur suivante lorsque je veux accéder à des adresses spécifiques en faisant "array+i" dans la fonction memcpy par example :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: pointer of type ` void * ' used in arithmetic
    J'ai donc déclaré ce tableau en tant que char* afin de pouvoir copier byte par byte les données.
    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
     
    numberSize = 4;  /*Test avec des int*/
    char* array = malloc(i*numberSize);
    Element* element = Stack->first
    while (i<20)
    {
    	printf("Nombre = %d I = %d\n",*(int*)element->number,i);
    	memcpy(array+(i*numberSize),element->number,numberSize);
    	element = element->next;
    	i++;
    	}
    }
    for(int j=0;j<20;j++)
    {
    	printf("Nombre %d = %d\n",j,array[j]);
    }
    J'obtient la sortie suivante :
    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
     
    Nombre 0 = 220 I = 0
    Nombre 1 = 210 I = 1
    Nombre 2 = 200 I = 2
    Nombre 3 = 190 I = 3
    Nombre 4 = 180 I = 4
    Nombre 5 = 170 I = 5
    Nombre 6 = 160 I = 6
    Nombre 7 = 150 I = 7
    Nombre 8 = 140 I = 8
    Nombre 9 = 130 I = 9
    Nombre 10 = 120 I = 10
    Nombre 11 = 110 I = 11
    Nombre 12 = 100 I = 12
    Nombre 13 = 90 I = 13
    Nombre 14 = 80 I = 14
    Nombre 15 = 70 I = 15
    Nombre 16 = 60 I = 16
    Nombre 17 = 50 I = 17
    Nombre 18 = 40 I = 18
    Nombre 19 = 30 I = 19
    Nombre 0 = -36
    Nombre 1 = 0
    Nombre 2 = 0
    Nombre 3 = 0
    Nombre 4 = -46
    Nombre 5 = 0
    Nombre 6 = 0
    Nombre 7 = 0
    Nombre 8 = -56
    Nombre 9 = 0
    Nombre 10 = 0
    Nombre 11 = 0
    Nombre 12 = -66
    Nombre 13 = 0
    Nombre 14 = 0
    Nombre 15 = 0
    Nombre 16 = -76
    Nombre 17 = 0
    Nombre 18 = 0
    Nombre 19 = 0
    Ce n'est donc pas du tout les bons nombres ...

    En changeant l'affichage ( array[numberSize*i] au lieu de array[i] ) , j'obtient la sortie suivante :

    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
     
    Nombre 0 = 220 I = 0
    Nombre 1 = 210 I = 1
    Nombre 2 = 200 I = 2
    Nombre 3 = 190 I = 3
    Nombre 4 = 180 I = 4
    Nombre 5 = 170 I = 5
    Nombre 6 = 160 I = 6
    Nombre 7 = 150 I = 7
    Nombre 8 = 140 I = 8
    Nombre 9 = 130 I = 9
    Nombre 10 = 120 I = 10
    Nombre 11 = 110 I = 11
    Nombre 12 = 100 I = 12
    Nombre 13 = 90 I = 13
    Nombre 14 = 80 I = 14
    Nombre 15 = 70 I = 15
    Nombre 16 = 60 I = 16
    Nombre 17 = 50 I = 17
    Nombre 18 = 40 I = 18
    Nombre 19 = 30 I = 19
    Nombre 0 = -36
    Nombre 1 = -46
    Nombre 2 = -56
    Nombre 3 = -66
    Nombre 4 = -76
    Nombre 5 = -86
    Nombre 6 = -96
    Nombre 7 = -106
    Nombre 8 = -116
    Nombre 9 = -126
    Nombre 10 = 120
    Nombre 11 = 110
    Nombre 12 = 100
    Nombre 13 = 90
    Nombre 14 = 80
    Nombre 15 = 70
    Nombre 16 = 60
    Nombre 17 = 50
    Nombre 18 = 40
    Nombre 19 = 30
    J'en déduit qu'il a essayé de coder les nombres sur un seul byte, tous les "numberSize" byte...

    Je ne sais pas trop comment m'en sortir avec tout cela. Une solution ?

    Merci d'avance.

    Quentin

  2. #2
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    En vrac :
    • tu ne peux pas indexer un bloc mémoire de type void * car ses éléments seraient des void (que vaudrait leur taille ?), en revanche tu peux indexer un bloc de type void ** ;
    • utilise toujours l'opérateur sizeof pour préciser la taille d'un type ;
    • tu as d'autres alternatives plus sécurisées pour définir des types génériques en C, préfère plutôt un tableau de pointeurs vers des union ou des macros (cf. exemple ci-dessous).


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #define DECL_STACK(Type) typedef struct { \
        Type *elems; \
        unsigned int capacity, \
                     count; \
    } stack_##Type##_t;
     
    /* ... */
     
    DECL_STACK(int)
    stack_int_t st;
    // ...

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Par défaut
    Merci pour ta réponse.
    Oui, effectivement ...
    En fait, J'essaie de créer une structure générique tout en utilisant le moins d'espace mémoire possible car celui-ci sera critique dans mon application.
    je ne pense pas qu'union soit une bonne idée pour moi car il fixerait seulement la limite haute des types de données que je lui donnerais par la suite.
    Les macros sont effectivement une bonne idée, je n'en ai encore jamais utilisé.
    Donc si je suis le raisonnement, il faut que je crée une autre macro qui permettrait de créer un tableau du type donné (int, double, long double ... ) ?

  4. #4
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Comment sais-tu que la mémoire disponible viendra à manquer ? N'« optimise » jamais prématurément : code la fonctionnalité, constate des performances insuffisantes ou un dysfonctionnement, fais des mesures, optimise. Dans cet ordre.

    De plus le fait que ta structure soit générique n'a aucune influence sur l'empreinte mémoire de ton programme, ça permet simplement de réutiliser du code.

    Pour préciser mon exemple ci-avant : je n'ai pas inclus dans la macro toute l'interface de gestion de la structure de données. Typiquement tu as aussi besoin de fonctions pour créer et détruire une instance de la structure, ajouter un élément, retirer un élément, etc... Les besoins exacts diffèrent selon les cas d'utilisation. Mais tu n'as besoin que d'une seul définition générique, ensuite tu peux déclarer autant de types spécialisés que nécessaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DECL_STACK(int)
    typedef unsigned int uint; // pour obtenir 'unsigned int' en un seul terme
    DECL_STACK(uint)
    DECL_STACK(float)
    DECL_STACK(double)
    ...
     
    {
        stack_uint_t st_uint_0;
        stack_float_t st_float_0;
        stack_float_t st_float_1;
        stack_float_t st_float_2;
        ...
    }

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Par défaut
    Ce sera embarqué et je n'aurai que quelques quelques dizaines de Ko de disponible.
    D'accord, merci beaucoup, je vais développer ce que j'ai fait avec des macros.

  6. #6
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    En fonction de l'application, quelques dizaines de kilos peuvent s'avérer tout à fait confortables.

    Soit tu peux prévoir une limite haute pour l'empreinte de ton programme qui te permet de dire si oui ou non la mémoire disponible sera suffisante et d'agir en amont, soit tu ne peux pas et il faut que tu implémentes d'abord la fonctionnalité puis que tu profiles tes cas d'utilisation.

    Et puis de la mémoire qui reste inutilisée, c'est gâché.

Discussions similaires

  1. Copie d'un buffer dans une structure
    Par KnightsOfTheRound dans le forum C++
    Réponses: 6
    Dernier message: 29/12/2005, 15h00
  2. Récuperer un nombre dans une chaine de caractère
    Par ColonelHati dans le forum C
    Réponses: 4
    Dernier message: 27/04/2005, 14h50
  3. Enlver un noeud dans une structure XML
    Par Sharingan dans le forum ASP
    Réponses: 4
    Dernier message: 20/12/2004, 08h08
  4. donée de plusieur vecteur dans une structure ??
    Par lipczynski dans le forum C++
    Réponses: 5
    Dernier message: 13/08/2004, 08h17
  5. type void* dans une structure
    Par barbapapaz dans le forum C
    Réponses: 3
    Dernier message: 16/07/2004, 16h11

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