Fournir parametre a un tableau de structure static extern [Résolu/Fermé]

Signaler
Messages postés
334
Date d'inscription
mardi 24 février 2015
Statut
Membre
Dernière intervention
29 novembre 2019
-
 astrocurieux -
Bonjour,

j'ai un tableau de structure en global plutôt cool que j'ai définie dans mon fichier.h

typedef struct s_tab
{
    int    a;
    int    b;
    int    c;
}                     t_tab;

extern  t_tab Tab[ ???? ];


Je voudrais que ce dernier tableau static soit de taille un int passé en paramètre du main()

voici un aperçut de ce que je cherche a faire.

main.c

t_tab     Tab[atoi(av[1]);

int     main(int ac, char **av)
{
for (int i = 0; i < 1000; i++)
              Tab[i] = i;
}



Comment faire pour que ma global récupère l'argument de mon main ?
j’attends vos réponses avec impatience.
merci.

2 réponses

Messages postés
4068
Date d'inscription
jeudi 18 août 2011
Statut
Membre
Dernière intervention
19 juin 2017
704
Tu ne peux pas faire ça :
tu essaie de réserver à l'avance une taille inconnue.
Tu peux par contre réserver un pointeur vers un tableau de taille connue lors de l'exécution du main, ce qui ne pose pas de problème vu que le main est exécuté en premier.

Deux solutions s'offrent à toi:
allouer ton tableau dans la pile de ton main, comme ceci:
#include <stdio.h>
#include <stdlib.h>

typedef struct s_tab
{
  int    a;
  int    b;
  int    c;
} t_tab;

t_tab     *Tab;

int main(int ac, char **av)
{
  int size = atoi(av[1]);

  printf("Size is %d\n", size);

  t_tab     lTab[size];
  Tab = lTab;

  for (int i = 0; i < size ; i++)
    Tab[i].a = i;
  for (int i = 0; i < size ; i++)
    if (Tab[i].a != i)
      {
        printf("error !\n");
        return -1;
      }
}


cela pose des problèmes de sécurité et de stabilité, car la taille de ton tableau fera varier le nombre maximum de fonctions imbriquées que tu pourra appeler après son allocation.

Tu peux aussi choisir de l'allouer dynamiquement, sur le tas.

#include <stdio.h>
#include <stdlib.h>

typedef struct s_tab
{
  int    a;
  int    b;
  int    c;
} t_tab;

t_tab     *Tab;

int main(int ac, char **av)
{
  int size = atoi(av[1]);

  printf("Size is %d\n", size);
  Tab = malloc(size);

  for (int i = 0; i < size ; i++)
    Tab[i].a = i;
  for (int i = 0; i < size ; i++)
    if (Tab[i].a != i)
      {
        printf("error !\n");
        return -1;
      }
  free(Tab);
}


Les défauts cités plus haut ne sont pas présents, mais il y a maintenant la contrainte de libérer la mémoire allouée.
Si c'est une allocation unique, ce n'est pas si grave, mais c'est une mauvaise habitude à ne pas prendre.

Cordialement, Sugel.
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 766
C'est quoi la différence entre son code :
t_tab Tab[atoi(av[1]);
et ta version
int size = atoi(av[1]);t_tab lTab[size]; ?

Dans les deux cas, cela est possible en C99...
Note : return -1 n'est pas standard. Il faut mettre : return EXIT_FAILURE.
Note2: tu as oublié d'inclure le stdio.h.
Messages postés
568
Date d'inscription
dimanche 7 février 2016
Statut
Membre
Dernière intervention
13 juin 2021
76 >
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016

La différence est dans le fait que le code est dans une fonction et pas en global.
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 766
Ah oui, j'avais pas fait attention que c'était en global. J'enlève cette partie-là de mon commentaire alors :-).
Messages postés
4068
Date d'inscription
jeudi 18 août 2011
Statut
Membre
Dernière intervention
19 juin 2017
704
hé, j'ai rien fait moi :c
j'ai bien inclus stdio, et osef du code de retour, il ne corresponds à rien de particulier ici
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 766
Ben, dans ton poste tu parles des bonnes habitudes à prendre et tu ne mets pas une valeur standard en retour du main(). C'est dommage.

Merci Sugel.
voila une réponse comme ont en voudrais a chaque questions !
simple, complet et très bien décrie.

je prend l'option n°2 : allocation dynamique

j'ai suivie tes indications a la lettre mais je ne compile malheureusement pas ....

Mon compilo me dit qu'il ne reconnais pas t_tab "Unknown type name"
et m'indique la ligne ou je déclare mon tableau entre ma structure et mon main()

es que j'ai bien fait de supprimer ma structure dans mon file.h ?
étant donner que je l'ai déplacer au dessus du main() ?
j'ai également supprimer la déclaration du tableau en extern qui s'y trouvé.

merci de votre investissement, j'avance bien grâce a vous !
bonne soirée .
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 766
Non ce n'est pas obligatoire. Mais dans ce cas, il faut passer par un double pointeur.

peut tu me l'illustrer avec le bout de code fournie plus haut pour que je soit certain de bien comprendre ?

car effectivement j'ai une bonne vielle erreur de segmentation qui débarque de nul part sans raison apparente donc il y a des chance que ce soit a cause de sa ..
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 766
Normal, l'erreur de segmentation. Tu souhaites modifier l'adresse qui est passée en tant que valeur. Voici un exemple :
#include <stdio.h>
#include <stdlib.h>

int* allocation(int ** const tab, const size_t n) {
     if (n < 0) {
          return NULL;
     }
     *tab = malloc(n * sizeof **tab);
     return *tab;
}

int main(void) {
     int *tab;
     
     tab=allocation(&tab,5);
     if (tab == NULL) {
          fputs("erreur d'allocation\n", stderr);
          return EXIT_FAILURE;
     }
     /*reste du traitement*/

     return EXIT_SUCCESS;
}

Je te laisse adapter ce code.

Merci fiddy,
effectivement c'est logique de ce point de vue .

je ne parvient pas a adapter ton code au miens ceci dit ...

voici un aperçut de mon environnement :

file.h

[...]
typedef struct s_Dat
{
      int a;
      int b;
      int c;
}                    t_Dat;

extern t_Dat   *Him;

t_Dat    *Allocat(t_Dat ** const tab, const size_t size);
[...]


main.c
t_Dat   *Him;

int     main(int ac, char  **av)
{
       Parsing(ac, av);
       free(Him)
}



file.c
t_Dat    *Him;

void    Parsing(int ac, char **av)
{
   [...]
   if ((*Him = Allocat(&Him, size)) == NULL)
       error_allocat();
   [...]
}

t_Dat  *Allocat(t_Dat ** const tab, const size_t size)
{
   if (size < 0)
           return (NULL);
   else
        *tab = malloc(size * sizeof **tab);
  return *tab;
}



le compilo
> incompatible types when assigning to type 't_Dat' from type 'struct t_Dat *'

j'ai beau chercher je ne comprend pas comment rendre heureux mon compilo ...
il est parfois aussi compliqué que les femmes a comprendre.

autant pour moi sa fonctionne bien.
j'ai supprimer les étoiles devant le nom de ma structure lors de l'appel de fonction d'allocation.

je te remercie beaucoup Fiddy, une fois de plus tu me débloque !
je passe en resolut