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 :

taille maximale d'un tableau à 3 dimensions?


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
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Par défaut taille maximale d'un tableau à 3 dimensions?
    Bonjour cher communauté

    J'essaye d'écrire un bout de code qui "m'extrait" tous les trigrammes (trois lettres consécutives) d'une (longue) liste de mots.
    L'idée c'était de déclarer un tableau à 3 dimension, et que lorsqu'on rencontre par exemple la suite de caractères 'a' 'b' 'c' dans la liste on fait:
    tab['a']['b']['c']++; ainsi en consultant le tableau je peux savoir que "abc" est présent 1 fois (je transforme les caractères en unsigned avant pour ne pas avoir tab[-1][][] par exemple)...
    Mon problème:
    Windows n'aime pas du tout int tab[256][256][256]={{{}}};, j'imagine que c'est une question de taille/mémoire?
    Je débute en C, et je vois pas de solutions (j'ai réduit le tableau à tab[50][50][50] pour stocker uniquement les caractères qui m'intéressent, mais ça n'a rien changé).
    Si vous avez des idées pour résoudre ce problème de mémoire, ou une meilleure façon de stocker les données (structure?, malloc?), je suis preneur!!!

    merci

  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
    Tu ne décris pas précisément ton erreur. Montre du code. Que se passe-t-il ?

    256 int au cube ça fait 4 à 8*16 MiB, c'est trop pour la pile (on peut s'en assurer avec ulimit -s). Ça passe en variable globale mais tu perds de la place : tu n'as besoin que des caractères alphabétiques a-z si tu te limites à l'ASCII. 50 int au cube c'est pas énorme, ça devrait passer sur la pile (et c'est encore un peu large).

    Tu ne feras pas l'économie d'une conversion de char vers size_t, ne serait-ce que pour rejeter les caractères qui ne sont pas dans la plage traitée, convertir les majuscules, etc..

    Ton idée est bonne, c'est probablement sa mise en œuvre qui pèche.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Un malloc pointeur pourrait convenir, puisque tu déporterais la mémoire utilisée dans le tas.
    Penses toutefois à "linéariser" ton tableau.
    Tu peux allouer malloc(N*N*N*sizeof(int)), et utiliser pointeur résultant ainsi: tab[c1 + N*c2 + N*N*c3]. avec N un const int.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Par défaut
    Merci pour les réponses, je teste ça...

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Par défaut
    Bon... ça marche pô

    j'ai essayé ça (pour expérimenter):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
        int tab[256][256][256]= {{{}}};
        tab[255][255][255] = 42;
        printf("%d", tab[255][255][255]);
    }
    évidemment ça ne marche pas...
    mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
    #include <stdlib.h>
    int tab[256][256][256]= {{{}}};
    int main()
    {
        tab[255][255][255] = 42;
        printf("%d", tab[255][255][255]);
    }
    marche sans soucis, donc merci pour l'astuce Matt_Houston (j'ai pas bien compris pourquoi par contre...)

    Mais quand j'utilise ça dans mon code ça ne marche pas quand même (peut-être que l'erreur viens d'ailleurs!).
    Je vous mets les lignes concernées: (je pense que vous allez trouvez ça moche et illisible, n'hésitez pas à critiquer )

    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
    int caracteresATraiter(const char c)
    {
        if(c >= 'a' && c <= 'z')
        {
            return TRUE;
        }
        else if(c >= 'A' && c <= 'Z')
        {
            return TRUE;
        }
        else if(    c=='â' || c=='ê' || c=='î' || c=='ô' || c=='û'
                 || c=='ä' || c=='ë'|| c=='ï' || c=='ö' || c=='ü'
                 || c=='Â' || c=='Ê'|| c=='Î' || c=='Ô' || c=='Û'
                 || c=='Ä' || c=='Ë'|| c=='Ï' || c=='Ö' || c=='Ü'
                 || c=='é' || c=='è'|| c=='ù' || c=='à' || c=='ç'
                 || c=='-' || c=='æ' || c=='œ'|| c=='Æ' || c=='Œ')
     
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    et puis ça aussi:
    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
    void extraireTrigrammes(FILE *output, FILE *trigra)
    {
        unsigned char conversionAvers0[TAILLE_TAB] = {}; // je remap les caractères qui m'intéressent pour pouvoir réduire mon tableau
        unsigned char conversion0versA[TAILLE_TAB] = {}; 
        unsigned char c = 'a', c1, c2, c3;
        int i, j, k;
     
        // Initialisation des tableaux de conversion: --------------------------
        j=0;
        for(i=0;i<255;i++) // conversion de 'a' vers 0
        {                  
            if(caracteresATraiter(i)) // si on tombe sur un caractère intéressant
            {
                conversionAvers0[i]=j; // conversion['a'] = 0, conversion['b'] = 1...
                j++;
            }
        }
        conversionAvers0['\n'] = j; // je traite \n à part car ça m'embête de le mettre dans caractereATraiter (j'ai d'autres fonctions qui l'utiilisent)
     
        j=0;
        for(i=0;i<256;i++) // conversion de 0 vers 'a'
        {
            if(caracteresATraiter(i) && !isupper(i))
            {
                conversion0versA[j] = i;
                j++;
            }
        }
        conversion0versA[j] = ' '; j++;
        // Fin Initialisation des tableaux de conversion: -----------------------
     
        // EXTRACTION
        int trigrammes[TAILLE_TAB][TAILLE_TAB][TAILLE_TAB];
        fseek(output, 0, SEEK_SET);
        while(c != 255) // On parcourt tout le fichier
        {
            c = (c1=fgetc(output));
            if(c != '\n' && c != 255)
            {
                c = (c2=fgetc(output));
                while(c != '\n' && c != 255)
                {
                    c = (c3=fgetc(output));
                    if(c != '\n' && c != 255)
                    {
                        trigrammes[conversionAvers0[c1]][conversionAvers0[c2]][conversionAvers0[c3]]++;
                        c1 = c2;
                        c2 = c3;
                    }
                }
             }
        }
     
     
        // Stockage dans trigra.txt...
        fseek(trigra, 0, SEEK_SET);
     
        for(i=0;i<TAILLE_TAB;i++)
        {
            fprintf(trigra, "\n");
            for(j=0;j<TAILLE_TAB;j++)
            {
                fprintf(trigra, "\n");
                for(k=0;k<TAILLE_TAB;k++)
                {
                    if(trigrammes[i][j][k])
                    {
                        fprintf(trigra, "%c%c%c:%5d |",conversion0versA[i], conversion0versA[j], conversion0versA[k], trigrammes[i][j][k]);
                    }
     
                }
            }
        }
     
     
    }
    Dans mon .h j'ai ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #define TAILLE_TAB 84 // Elle dépend du nombre de caractère différents qu'on va traiter!
    #define TRUE 1
    #define FALSE 0
     
    extern int trigrammes[TAILLE_TAB][TAILLE_TAB][TAILLE_TAB];
    voila voila, désolé si c'est pas propre, c'est la 1ère fois que je poste un code...

  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
    Citation Envoyé par Janosch89 Voir le message
    Bon... ça marche pô
    [...]
    évidemment ça ne marche pas...
    [...]
    ça ne marche pas quand même
    Mais encore ? Décris précisément les erreurs rencontrées, nous sommes des êtres humains.


    Citation Envoyé par Janosch89 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int tab[256][256][256]= {{{}}};
    Cette syntaxe d'initialisation n'est pas permise en C, compile avec -pedantic -Werror (je suppose GCC / Clang) pour recevoir : error: ISO C forbids empty initializer braces. Remplace cela par {{{ 0 }}}, ou rien du tout si le tableau est global (les variables globales sont initialisées à zéro).

    D'une manière générale active tous les avertissements : -std=c11 -pedantic -Wall -Wextra .


    Citation Envoyé par Janosch89 Voir le message
    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
    int caracteresATraiter(const char c)
    {
        if(c >= 'a' && c <= 'z')
        {
            return TRUE;
        }
        else if(c >= 'A' && c <= 'Z')
        {
            return TRUE;
        }
        else if(    c=='â' || c=='ê' || c=='î' || c=='ô' || c=='û'
                 || c=='ä' || c=='ë'|| c=='ï' || c=='ö' || c=='ü'
                 || c=='Â' || c=='Ê'|| c=='Î' || c=='Ô' || c=='Û'
                 || c=='Ä' || c=='Ë'|| c=='Ï' || c=='Ö' || c=='Ü'
                 || c=='é' || c=='è'|| c=='ù' || c=='à' || c=='ç'
                 || c=='-' || c=='æ' || c=='œ'|| c=='Æ' || c=='Œ')
     
        {
            return TRUE;
        }
        else
        {
            return FALSE;
        }
    }
    Attention, ce programme ne fonctionnera qu'avec des fichiers encodés en 8859-1 (exit l'UTF-8) et encore partiellement : bien qu'il n'occupe qu'un seul octet dans cet encodage le symbole œ par exemple est composé de deux glyphes et œu est donc un trigramme à part entière, contrairement à œuf.

    À ta place j'écrirais une fonction qui prend un char et retourne une valeur d'index de type size_t qu'on pourrait utiliser directement pour adresser les cases du tableau. Quelque chose du style de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #define TABLE_SIZE ((size_t)26)
    size_t occurrences[TABLE_SIZE][TABLE_SIZE][TABLE_SIZE];
     
    #define INDEX_INVALID ~((size_t)0) // 0xffffff..
     
    // ...
     
        if ((a = char_to_index(c[0])) != INDEX_INVALID
         && (b = char_to_index(c[1])) != INDEX_INVALID
         && (c = char_to_index(c[2])) != INDEX_INVALID) {
            ++occurrences[a][b][c];
     
            // ...

    Citation Envoyé par Janosch89 Voir le message
    marche sans soucis, donc merci pour l'astuce Matt_Houston (j'ai pas bien compris pourquoi par contre...)
    Le tableau du premier programme est déclaré au sein d'une fonction, donc dit à portée locale et alloué sur la pile d'exécution dont la taille est limitée (on peut supposer qu'on dispose de 2 MiB ou plus sur un système relativement récent, mais ce n'est pas garanti). Le tableau du second programme est déclaré en tant que variable à portée globale et à ce titre alloué au démarrage du programme à un emplacement immuable pour la durée de l'exécution.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 7
    Par défaut
    Cool, pleins d'infos! merci

    J'ai les pâtes qui sont en train de déborder, donc pas trop le temps de répondre, je regarde tout ça ce soir (nuit?)...

    Pour être plus précis sur l'erreur:
    à partir d'une certaine taille pour TAILLE_TAB (autour de 41 je crois...) mon fichier trigra est vide.
    En dessous, tout se passe bien.

    edit: j'utilise la sdl (GUI), donc j'ai pas de console, et donc pas de message d'erreur.
    mais je vais passer en console, ça va être plus simple je pense...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Taille maximale d'un tableau de char
    Par ickis69 dans le forum Débuter
    Réponses: 33
    Dernier message: 06/04/2012, 10h38
  2. [XHTML 1.0] Taille maximale d'un tableau
    Par ne2sbeal dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 05/03/2010, 11h23
  3. [Tableaux] Taille maximale d'un tableau
    Par estacado dans le forum Langage
    Réponses: 7
    Dernier message: 25/07/2007, 21h20
  4. [Tableaux] Taille maximale d'un tableau
    Par Bisûnûrs dans le forum Langage
    Réponses: 3
    Dernier message: 15/02/2007, 18h53
  5. [langage] taille maximale d'un tableau ?
    Par Jasmine80 dans le forum Langage
    Réponses: 10
    Dernier message: 10/11/2006, 09h41

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