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 :

Pointeur sur tableau de structures imbriquées


Sujet :

C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut Pointeur sur tableau de structures imbriquées
    Bonjour,

    Je sollicite votre aide concernant un problème avec des pointeurs sur des tableaux de structures imbriquées.
    Pour mon petit développement, j'ai besoin utilisé contenant des tableaux de données dont je ne connais pas la taille (car définit par l'utilisateur).

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    #include "stdafx.h"
     
    //Includes system
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    //Declaration de type
    typedef struct SubData_t
    {
    	double*		nb_array;
    }SubData;
     
    typedef struct Data_t
    {
    	SubData*	sub_array;
    }Data;
     
    void subadd(SubData* p_sub)
    {
    	int		i,n=3;
     
    	p_sub->nb_array = (double*)calloc(3, sizeof(double));
     
    	for (i = 0; i < n; i++)
    	{
    		p_sub->nb_array[i] = (double)i;
    	}
     
    }
     
    void add(Data* p_data)
    {
    	int		i, n = 3;
     
    	p_data->sub_array = (SubData*)calloc(3, sizeof(SubData));
     
    	for (i = 0; i < n; i++)
    	{
    		subadd(&p_data->sub_array[i]);
    	}
    }
     
     
     
    int main()
    {
    	int			i,j,k,n = 2,size,size_1,size_2;
    	Data*		array;
     
    	int			a, b;
    	//Data		temp;
     
    	array = (Data*)calloc(n, sizeof(Data));
     
    	for (i = 0; i < n; i++)
    	{
    		add(&array[i]);
    	}
     
    	a = sizeof(array);
    	b = sizeof(Data);
     
    	size = sizeof(arr) / sizeof(Data);
     
    	for (i = 0; i < size; i++)
    	{
    		printf("Arr [%d] \n", i);
     
    		size_1 = sizeof(array[i].sub_array) / sizeof(SubData);
     
    		for (j = 0; j < size_1; j++)
    		{
    			printf("\tSubarr [%d] \n", j);
     
    			size_2 = sizeof(array[i].sub_array[j].nb_array) / sizeof(double);
     
    			for (k = 0; k < size_2; k++)
    			{
    				printf("\t\tnb_arr [%d] = %f \n", k, array[i].sub_array[j].nb_arr[k]);
     
    			}
    		}
     
    	}
     
     
        return 0;
    }

    Pour faire des essais, j'ai écris le code suivant très simplifié et la je rencontre de gros problèmes :
    Les tailles des tableaux, ici, sont fixes pour l'exemple. En réalité, elles seront dynamiques (réallocations de mémoire), je commence simplement déjà.

    toutes les valeurs de size, size_1, size_2 représentant le nombre d'éléments de mes tableaux sont erronés.
    exemple : size = 0, a = 4 et b=8, alors que size devrait être égale à 2 puisque je mets 2 éléments dans mon tableau. 4/8 = 0.5 -> comme c'est un entier donc 0.
    Mais pourquoi a = 4 et non pas 16 car sizeof(Data) = 8, 2 éléments x 8 =16.

    Je ne comprends pas ce qui se passe. Et je me demande même si c'est bien la bonne manière de coder mon problème ? Est ce que je fais une/des erreurs de programmations.

    J’espère que quelqu'un aura la gentillesse de m'expliquer mon problème et surtout a cote de quoi je passe et si possible de donner un exemple de code.
    Cela fait 3 jours que je le casse la tête dessus.

    Je vous remercie d'avance de votre aide.

    Tof19100

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 548
    Points
    10 548
    Par défaut
    Je me suis pris la tête pendant 5 minutes mais tout est normal (donc un tableau de tableaux de tableaux de double, il faut suivre)
    Tu as fait l'erreur du noob niveau 0 - sizeof d'un pointeur sera toujours égal soit à 4 (compilation 32 bits) soit à 8 (compilation 64 bits)

    Voici le bon code qui fonctionne qu'avec de vrais tableaux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a[17];
    size_t n = sizeof(a)/sizeof(a[0]);
    //or size_t n = sizeof(a)/sizeof(int);
    Je regarde le code - cast de malloc, initialisation n'importe où des variables (autorisée depuis le C99) -> Est-ce que tu compiles en C++ ?

    Sinon je pourrais tellement dire - oubli des free, le préfixe _t mis sur le nom temporaire de la structure et non sur le nom qu'on va utiliser, les immondes &array[i], oubli de tester le retour des malloc

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Salut,

    Et oui noob, ça fait 20 ans (depuis mes études) que j'ai pas fait de C, le retour à la source est difficile ....
    le sizeof (array[0]) j'avais déjà essayé mais comme il me donnait une valeur erronée, je me suis dit que je me trompais.

    Merci pour tes remarques :
    - effectivement je compilais en C++ au lieu de C
    - j'ai modifie le code avec tes remarques
    pour les horribles array[i].sub_array[j].nb_array[k], je ne sais pas les écrire autrement
    - Ci-dessous le code modifié et cela ne marche toujours pas au niveau du calcul du nombre d'éléments des tableaux

    maintenant a = 4 et b = 4 -> size = 1 au lieu de 2

    rrrrrrrrrrrrahhhhhhhhhhhh

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    #include "stdafx.h"
     
    //Includes system
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    //Declaration de type
    typedef struct SubData
    {
    	double*		nb_array;
    }SubData_t;
     
    typedef struct Data
    {
    	SubData_t*	sub_array;
    }Data_t;
     
    int subadd(SubData_t* p_sub)
    {
    	int		i,n=3;
    	double	value = 1.23456789;
     
    	p_sub->nb_array = (double*)calloc(3, sizeof(double));
    	if (p_sub->nb_array == NULL) return -1;
     
    	for (i = 0; i < n; i++)
    		p_sub->nb_array[i] = value*i;
     
    	return 0;
    }
     
    int add(Data_t* p_data)
    {
    	int		i, n = 3;
     
    	p_data->sub_array = calloc(3, sizeof(SubData_t));
    	if (p_data->sub_array == NULL) return -1;
     
    	for (i = 0; i < n; i++)
    		subadd(&p_data->sub_array[i]);
     
    	return 0;
    }
     
    int main()
    {
    	int			i, j, k, n = 2;
    	size_t		size,size_1,size_2;
    	Data_t*		array;
     
    	int			a, b;
     
    	array = calloc(n, sizeof(Data_t));
    	if (array == NULL) return -1;
     
    	for (i = 0; i < n; i++)
    	{
    		add(array+i);
    	}
     
    	a = sizeof(array);
    	b = sizeof(array[0]);
     
    	//size = sizeof(array) / sizeof(Data_t);
    	size = sizeof(array) / sizeof(array[0]);
     
    	for (i = 0; i < (int)size; i++)
    	{
    		printf("Array [%d] \n", i);
     
    		size_1 = sizeof(array[i].sub_array) / sizeof(SubData_t);
     
    		for (j = 0; j < (int)size_1; j++)
    		{
    			printf("\tSubArray [%d] \n", j);
     
    			size_2 = sizeof(array[i].sub_array[j].nb_array) / sizeof(double);
     
    			for (k = 0; k < (int)size_2; k++)
    			{
    				printf("\t\tNb_Array [%d] = %f \n", k, array[i].sub_array[j].nb_array[k]);
     
    				free(&(array[i].sub_array[j].nb_array[k]));
    			}
     
    			free(&(array[i].sub_array[j]));
    		}
     
    		free(&array[i]);
     
    	}
     
    	free(array);
     
        return 0;
    }
    Merci pour ton aide.

  4. #4
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Ça y est je viens de percuter, je ne peux pas trouver le nombre d’éléments de mon tableau en fait car c'est un pointeur.
    Il faut que je les compte et stocke le nombre d’éléments de mon tableau dans ma struct.

    Ci-dessous le code modifié :

    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
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    //Includes system
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
     
    //Declaration de type
    typedef struct SubData
    {
    	int			size;
    	double*		nb_array;
    }SubData_t;
     
    typedef struct Data
    {
    	int			size;
    	SubData_t*	sub_array;
    }Data_t;
     
    int subadd(SubData_t* p_sub)
    {
    	int		i,n=3;
    	double	value = 1.23456789;
     
    	p_sub->nb_array = calloc(n, sizeof(double));
    	if (p_sub->nb_array == NULL) return -1;
     
    	for (i = 0; i < n; i++)
    	{
    		p_sub->nb_array[i] = value*i;
    		p_sub->size = i+1;
    	}
     
    	return 0;
    }
     
    int add(Data_t* p_data)
    {
    	int		i,n=3;
    	int		err;
     
    	p_data->sub_array = calloc(n, sizeof(SubData_t));
    	if (p_data->sub_array == NULL) return -1;
     
    	for (i = 0; i < n; i++)
    	{
    		err = subadd(&p_data->sub_array[i]);
    		p_data->size = i+1;
    		if (err != 0) return err;
    	}
     
    	return 0;
    }
     
    int main()
    {
    	int			i, j, k, n = 2;
    	int			err = 0;
    	Data_t*		array;
     
    	array = calloc(n, sizeof(Data_t));
    	if (array == NULL) return -1;
     
    	for (i = 0; i < n; i++)
    		err = add(array+i);
    	if (err != 0) return err;
     
    	for (i = 0; i < n; i++)
    	{
    		printf("Array [%d] \n", i);
     
    		for (j = 0; j < array[i].sub_array[j].size; j++)
    		{
    			printf("\tSubArray [%d] \n", j);
     
    			for (k = 0; k < array[i].sub_array[j].size; k++)
    					printf("\t\tNb_Array [%d] = %f \n", k, array[i].sub_array[j].nb_array[k]);
     
    			free(array[i].sub_array[j].nb_array);
     
    		}
     
    		free(array[i].sub_array);
    	}
     
    	free(array);
     
        return 0;
    }
    Est-ce qu'il existe un autre moyen ?

    Merci.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 627
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 627
    Points : 10 548
    Points
    10 548
    Par défaut
    Citation Envoyé par ToF19100 Voir le message
    Est-ce qu'il existe un autre moyen ?
    Il [me semble qu'il] n'y a qu'une sentinelle qui puisse indiquer la fin de ton tableau. (<- lien wiki en français)
    Par exemple :
    1. le caractère '\0' est la sentinelle d'une chaîne de caractères
    2. NULL est la sentinelle d'une liste chaînée


    Mais la sentinelle n'empêche pas de parcourir ses données pour calculer la taille.
    Donc stocker la taille est de toute manière la méthode la plus efficace en terme de temps

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 631
    Points : 30 865
    Points
    30 865
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par ToF19100 Voir le message
    Est-ce qu'il existe un autre moyen ?
    Non. On ne peut pas, sur un pointeur, connaitre la taille de la zone allouée.
    Seuls moyens: la sentinelle mentionnée par foetus ou bien mémoriser la taille réellement utilisée ; ce que je fais parfois quand je stocke des données en nombre variable => quand une donnée entre, j'incrémente un compteur interne et dès que le compteur atteint la taille allouée alors j'incrémente cette taille de N et je réalloue. Petit truc => dans tous les cas j'utilise realloc car si le pointeur initial est nul alors realloc se comporte comme malloc.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par ToF19100 Voir le message
    Et oui noob, ça fait 20 ans (depuis mes études) que j'ai pas fait de C, le retour à la source est difficile ....

    [...]

    - effectivement je compilais en C++ au lieu de C
    Et ça ne te dirait pas de faire du C++ ?

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 631
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 631
    Points : 30 865
    Points
    30 865
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Et ça ne te dirait pas de faire du C++ ?
    Attends, si on en est à recruter des futurs programmeurs autant le lancer sur de vrais langages qui roxxent leur race !!!

    Donc ça ne te dirait pas de faire du Python ?
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. pointeur sur tableau dans une structure
    Par rollbich dans le forum Débuter
    Réponses: 3
    Dernier message: 02/06/2013, 23h23
  2. JNA pointeur sur tableau de structure
    Par NyTR0 x dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 30/12/2009, 18h43
  3. Pointeur sur tableau de structure
    Par Mercenary Developer dans le forum Débuter
    Réponses: 3
    Dernier message: 22/09/2008, 09h35
  4. [VB6]Tri multi-colonnes sur tableau de structure
    Par ELGUEVEL dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 17/02/2006, 09h02

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