Partage
  • Partager sur Facebook
  • Partager sur Twitter

Créer un tableau à taille inconnue

    7 juin 2022 à 18:37:35

    Bonjour à tous,

    J'essaie de développer un fonction pour remplir un tableau dans une boucle for.

    Mon problème c'est que la taille du dit tableau peut changer en fonction des inputs.

    Donc j'ai quelque chose du genre :

    void maFonction(int start, int end, uint8_t* data)
    {
    int size = end - start;
    uint8_t monTableau[size] = {0};
    // do something }

    Sauf que bien évidemment, mon compilateur n'accepte pas monTableau[size].

    J'imagine que je suis pas le seul à m'être poser cette question donc je fais appel à votre expérience!

    Merci

    TY

    • Partager sur Facebook
    • Partager sur Twitter
      7 juin 2022 à 18:41:36

      On ne peut effectivement pas initialiser un VLA (tableau de taille variable, dépendant de variables à l'exécution) de cette façon.

      Solutions pour l'initialiser à 0

      • faire une boucle
      • fonction memset, (la fonction bzero est obsolete)
      • ...

      Il est probable qu'en écrivant une boucle simple, normale, de mise à zéro, le compilateur optimisera ça très bien

      -
      Edité par michelbillaud 8 juin 2022 à 0:14:12

      • Partager sur Facebook
      • Partager sur Twitter
        7 juin 2022 à 18:59:25

        Si tu disais plutôt ce que tu veux vraiment faire.
        Pourquoi le start et le end? et comment comptes-tu retourner le tableau au programme appelant?
        • Partager sur Facebook
        • Partager sur Twitter

        Le Tout est souvent plus grand que la somme de ses parties.

          7 juin 2022 à 19:07:10

          PierrotLeFou a écrit:

          et comment comptes-tu retourner le tableau au programme appelant?

          ThugYo a écrit:

          // do something

          Il ne compte peut-être pas le retourner ? Juste faire quelque chose avec dans la fonction ?



          • Partager sur Facebook
          • Partager sur Twitter
            7 juin 2022 à 19:26:35

            Si le tableau est un paramètre de la fonction, normalement on ne le déclare pas dans la fonction mais dans le programme appelant. 

            Une méthode souvent utilisée, c'est de déclarer un tableau de taille fixe égale au nombre maximal d'éléments possibles, et de lui adjoindre une variable indiquant le nombre effectif d'éléments. Le tableau et la variable doivent être passés en paramètres de la fonction.

            -
            Edité par robun 7 juin 2022 à 19:28:15

            • Partager sur Facebook
            • Partager sur Twitter
              7 juin 2022 à 19:33:46

              ThugYo a écrit:

              Sauf que bien évidemment, mon compilateur n'accepte pas monTableau[size].

              Quelle est la version du C que tu utilises pour compiler ? Toutes les compilations faites avec un C dont la version est >= C99 acceptent cette écriture (mais pas l'initialisation  [ ={0}; ] bien sur).

              -
              Edité par edgarjacobs 7 juin 2022 à 19:35:45

              • 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

                7 juin 2022 à 23:39:51

                Bonjour,

                Pierrot pose la bonne question :

                PierrotLeFou a écrit:

                Si tu disais plutôt ce que tu veux vraiment faire.
                Pourquoi le start et le end? et comment comptes-tu retourner le tableau au programme appelant?


                Avec le nom des paramètres on pourrait imaginer plein de chose, comme la copie d'une portion de tableau (faire un slice en quelque sorte), ou carrément autre chose … seul ThugYo pourra nous le dire.

                Rappelons tout de même qu'un VLA est alloué sur la pile, que la pile est une resource de taille limitée et partagée et qu'on peut vite l'exploser au runtime et que le VLA est automatiquement libéré à la fin de sa portée.

                • Partager sur Facebook
                • Partager sur Twitter
                  8 juin 2022 à 7:16:51

                  > on peut exploser vite la pile

                  Ça dépend évidemment de l'environnement dans lequel on travaille (taille de la pile) et de ce qu'on fait (tableau de quelques kilos octets / stockage en une image de DVD dans un tableau...)

                  Bref, si on a ce souci, on utilisera un tableau alloué dynamiquement, quelque chose comme

                  uint8_t * array = malloc(size * sizeof(array[0]));
                  
                  // vérifier que array != NULL
                  
                  memset(array, 0, size * sizeof(array[0]));
                  
                  // FAIRE LE BOULOT
                  
                  free(array);

                  Ne pas oublier de passer par un free quand on n'a plus besoin du tableau. Chaque solution technique a ses emmerdements.

                  Un autre problème avec les VLA, c'est si il y en a plusieurs. Le premier est stocké à un offset fixe du cadre de pile, mais pas les suivants, forcement. Ce qui complique (ralentit) l'adressage : la position d'un vla depend de la taille des précédents, taille qui n'est connue qu'a l'exécution.  Donc au mieux l'accès se fait via un pointeur sur le début de tableau.

                  -
                  Edité par michelbillaud 8 juin 2022 à 7:21:58

                  • Partager sur Facebook
                  • Partager sur Twitter
                    8 juin 2022 à 20:10:34

                    Pour créer un tableau à taille inconnue, tu doit créer un allouer dynamiquement (malloc) la mémoire à un pointeur avec la taille que tu veux.

                    Par exemple :

                    int main(void)
                    {
                        int tailleTableau = 5;
                        int *tableau = malloc(sizeof(int) * tailleTableau); // tu crée ton tableau (enfin c'est plutôt un pointeur)
                        if (tableau == NULL) // Tu vérifies
                        {
                            exit(0);
                        }


                    tableau[1] = 5; // Tu fais ce que t'as à faire.


                    free(tableau); // Tu libères la mémoire. return 0; }



                    -
                    Edité par WalterO'Brian1 8 juin 2022 à 20:13:30

                    • Partager sur Facebook
                    • Partager sur Twitter
                      9 juin 2022 à 2:24:52

                      Et tant qu'à vérifier, donner un message d'erreur:
                      -
                      #include <errno.h>     // stdlib.h  l'inclus.
                      ...
                          // Vérifier
                          if(tableau == NULL {
                              perror("nom_de_la_fonction");
                              fprintf(stderr, "Required: %d\n", tailleTableau * sizeof(int));
                              exit(EXIT_FAILURE);
                          }

                      -
                      Edité par PierrotLeFou 9 juin 2022 à 2:29:50

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Le Tout est souvent plus grand que la somme de ses parties.

                        9 juin 2022 à 10:56:22

                        Salut à tous,

                        Ce que je veux faire mettre en forme un trame que j'envoie sur un bus SPI. En gros, écrire une séquence d'octet sur le bus.

                        Le start et le end corresponde aux adresses des registres. Je souhaite construire un tableau contenant les informations à écrire dans les registres et la taille du tableau dépend des adresses en inputs.

                        • Partager sur Facebook
                        • Partager sur Twitter
                          9 juin 2022 à 11:24:20

                          En général ces registres sont connus à la compilation non ? Suffirait d'utiliser des vrai constantes si possible. Sinon malloc/calloc ou effectivement VLA si supporté.

                          • Partager sur Facebook
                          • Partager sur Twitter

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

                            10 juin 2022 à 6:05:40

                            Salut,

                            Sinon, quelle est la taille max des données que tu aurais à envoyer ? Si ça va de 4 à 50, tu as plus vite fais de déclarer une table de 64 tout de suite et ne pas te prendre la tête. Surtout si c'est juste pour économiser un peu de place, une alloc c'est au bas mot 80 octets de bouffés, même pour allouer un seul octet à cause de tout le book keeping qu'il y a autour.

                            C'est de quel matos vers quel matos ? Arduino, Raspberry, tes chips font quoi ? J'ai l'impression que tu essais de résoudre un problème que tu as avec une solution qui n'est pas la bonne, simple feeling;

                            En SPI, on trimballe rarement des trouzaines d'infos, et surtout tu as la main sur la sélection de chip et sur l'horloge, rien ne t'empêche de te limiter à 4 octets. Je lis 4 chez truc, je balance 4 à machin etc.

                            Les esclaves ne font pas ce qu'ils veulent, je ne vois pas à quel moment tu pourrais te laisser submerger par un chip qui aurait décidé de t'envoyer 2 To de données..

                            Bonne continuation.

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Bonhomme !! | Jeu de plateforme : Prototype.

                            Créer un tableau à taille inconnue

                            × 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