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 :

Incohérence dans un tableau deux dimensions


Sujet :

C

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut Incohérence dans un tableau deux dimensions
    Bonjour,
    J'ai fait une petite fonction toute simple qui devait à la base remplir un tableau à deux dimensions avec des entiers égaux à 0, cependant la première case [0][0] n'est jamais égale à 0, elle est égale à un chiffre qui varie à chaques executions, c'est la seule case qui a ce comportement étrange. Je sais pas si vous avez une idée d'où le problème pourrais venir.

    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
     
    int** transformArrayOfCharInArrayOfInt( char* nameOfFile, int width, int height)
    {
        int i = 0;
        int j = 0;
        FILE *file = NULL;
        file = fopen(nameOfFile,"r");
        char lineOfPixel[256];
        int **p = (int **)malloc(sizeof(int) * height);
        for (i = 0; i < height; i++)
        {
            p[i] = (int*) malloc(sizeof(int) * width);
            for (j = 0; j < width ; j++)
            {
                p[i][j] = 0;
            }
        }
        printf("%d \n", p[0][0]);
    }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 450
    Par défaut
    Bonjour et bienvenue,

    À la ligne 9, tu alloues des pointeurs et non directement des int, chose que tu fais en revanche à l'étape suivante. Donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        int **p = (int **)malloc(sizeof(int *) * height);
    Sur un PC en 32 bits, il se trouve qu'entiers ordinaires et pointeurs ont la même taille. En 64 bits, en revanche, tu auras des pointeurs sur 8 octets alors que les int, eux, resteront en général sur 4. Lorsque c'est le cas, ta ligne alloue deux fois moins de mémoire que nécessaire.

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut
    Merci beaucoup, j'ai une autre question, mon tableau étant correctement initialisé. Je veux récupérer une matrice dans un fichier de type PGM, pour cela j'ai créé une fonction "explode" qui prend en paramètre une chaine de caractère, le séparateur et la largeur du tableau de ma matrice et elle retourne un tableau d'entier. Cette fonction marche très bien mais quand je veux l'étendre à un tableau deux dimension y a un segfault et aucun printf apparait je ne peux donc pas savoir ou est le problème...:

    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
     
    int* explode(char* stringToExplode, char separator, int width)
    {
        int i = 0;
        int * finalArray[width];
        int indicator = 0;
        int buffer = 0;
        int cursor = 0;
        int length = strlen(stringToExplode);
        for (i = 0;i < length;i++)
        {
            if ( stringToExplode[i] ==
                 separator && indicator == -1)
                {
                    finalArray[cursor] = buffer;
                    cursor++;
                    indicator = 0;
                    buffer =  0;
                }
            else if ( stringToExplode[i] != separator)
                {
                    buffer = buffer * 10 + (stringToExplode[i] - 48);
                    indicator = -1;
                }
        }
        finalArray[cursor] = buffer;
        return finalArray;
    }
     
     
    int** transformArrayOfCharInArrayOfInt( char* nameOfFile, int width, int height)
    {
        int i = 0;
        int j = 0;
        FILE *file = NULL;
        file = fopen(nameOfFile,"r");
        char lineOfPixel[256];
        int **p = (int **)malloc(sizeof(int*) * height);
        for(i = 1; i < 4; i++)
        {
            fgets(lineOfPixel, 256 , file);
        }
        for (i = 0; i < height; i++)
        {
            p[i] = (int*) malloc(sizeof(int) * width);
            for (j = 0; j < width ; j++)
            {
                p[i][j] = explode(fgets(lineOfPixel, 256 , file), ' ', width)[j];
            }
        }
    }

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 450
    Par défaut
    Citation Envoyé par hypto Voir le message
    j'ai créé une fonction "explode" qui prend en paramètre une chaine de caractère, le séparateur et la largeur du tableau de ma matrice et elle retourne un tableau d'entier. Cette fonction marche très bien mais quand je veux l'étendre à un tableau deux dimension y a un segfault
    Il peut y avoir plusieurs raisons mais, en premier lieu, tu as encore le même problème : tu as alloué un tableau d'entiers mais tu le remplis avec des pointeurs (renvoyés par ta fonction explode). Ça plantera sur 64 bits.

    et aucun printf apparait je ne peux donc pas savoir ou est le problème...:
    C'est pour cela qu'il faut prendre l'habitude d'utiliser un débogueur. Si tu travailles sous Linux, par exemple, tu compiles ton programme avec l'option « -g » et tu utilises gdb pour le déboguer en temps réel.

    Et avant cela, il faut configurer ton compilateur pour qu'il soit strict dans le respect de la norme et, à tout le moins, qu'il t'affiche des avertissements à la moindre irrégularité, avertissements que tu t'efforceras d'éliminer. Avec GCC, tu peux commencer par « -std=c99 -Wall -pedantic ».

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut
    Bon j'ai plus de segfault, j'ai un peu du mal avec cette histoire de pointeur/entier quand est ce que j'alloue un tableau d'entier ou un tableau de pointeur... Ceci dit quand j'éxécute le programme et qu'il va lire cette image là:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    P2
    24 7
    15
    0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
    0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0
    0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0
    0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0
    0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0
    0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0
    0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
    il va me retourner:


    Enfin je veux dire les nombres qui apparaisent viennet du document, des 0 des 7 et des 1 ça ressemble pas à des nombres qui viennent d'un espace mémoire.

    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
     
     
    int* explode(char* stringToExplode, char separator, int width)
    {
        int i = 0;
        int * finalArray[width];
        int indicator = 0;
        int buffer = 0;
        int cursor = 0;
        int length = strlen(stringToExplode);
        for (i = 0;i < length;i++)
        {
            if ( stringToExplode[i] ==
                 separator && indicator == -1)
                {
                    finalArray[cursor] = buffer;
                    cursor++;
                    indicator = 0;
                    buffer =  0;
                }
            else if ( stringToExplode[i] != separator && stringToExplode[i] != '\n')
                {
                    buffer = buffer * 10 + (stringToExplode[i] - 48);
                    indicator = -1;
                }
        }
        finalArray[cursor] = buffer;
        return finalArray;
    }
     
    ////j'ai vérifié le tableau renvoyé par explode il est correct
     
     
    int** transformArrayOfCharInArrayOfInt( char* nameOfFile, int width, int height)
    {
        int i = 0;
        int j = 0;
        int k = 0;
        FILE *file = NULL;
        file = fopen(nameOfFile,"r");
        char lineOfPixel[256];
        int **p = (int **)malloc(sizeof(int*) * height);
        int *q = (int *)malloc(sizeof(int) * width);
        for(i = 0; i < 3; i++)
        {
            fgets(lineOfPixel, 256 , file);
        }
        fgets(lineOfPixel, 256,file);
        for (i = 1; i < height ; i++)
        {
            fgets(lineOfPixel, 256 , file);
            p[i] = (int*) malloc(sizeof(int) * width);
            q = explode(lineOfPixel, ' ', width);
            for (j = 0; j < width ; j++)
            {
                p[i][j] = q[j];            ////////// A mon avis le problème est ici
            }
        }
        for (i = 1; i < height; i++)
        {
            for (j = 0; j < width; j++)
            {
                printf("%d|",p[i][j]);
            }
            printf("\n");
        }
    }

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 450
    Par défaut
    Citation Envoyé par hypto Voir le message
    Bon j'ai plus de segfault, j'ai un peu du mal avec cette histoire de pointeur/entier quand est ce que j'alloue un tableau d'entier ou un tableau de pointeur...
    C'est-à-dire qu'avant même d'entrer dans les détails, lorsque tu fais une affectation avec « = », la première chose à vérifier est que le type est bien le même des deux cotés (ou qu'un cast automatique donnera toujours la bonne valeur). C'est une question de bon sens.

    Ici, tu alloues un tableau de « int », mais ta fonction renvoie un pointeur.

    Ceci dit quand j'éxécute le programme et qu'il va lire cette image là:il va me retourner:

    http://tinypic.com/r/2d1a14w/5

    Enfin je veux dire les nombres qui apparaisent viennet du document, des 0 des 7 et des 1 ça ressemble pas à des nombres qui viennent d'un espace mémoire.


    […]

    Il y a encore plusieurs erreurs mais pour commencer : à quoi sert le malloc() de la ligne 43 ? (Celle qui affecte q).

  7. #7
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut
    le malloc sert à alouer dynamiquement la mémoire pour le tableau q, ensuite je dit que le tableau q est le tableau qui est renvoyé par ma fonction explode.

  8. #8
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 450
    Par défaut
    Citation Envoyé par hypto Voir le message
    le malloc sert à alouer dynamiquement la mémoire pour le tableau q, ensuite je dit que le tableau q est le tableau qui est renvoyé par ma fonction explode.
    Oui, mais on ne travaille pas en Java. « q » est un pointeur qui sert simplement à recevoir une adresse mémoire et qui peut prendre n'importe quelle valeur, valide ou non.

    Dans le cas présent, tu utilises ce pointeur pour recueillir la valeur renvoyée par malloc(), laquelle correspond à l'emplacement de la zone mémoire allouée. Si tu utilises « q » par la suite pour stocker autre chose, en l'occurrence la valeur de retour de la fonction explode, tu écrases la valeur précédente.

    Tu as donc perdu l'adresse mémoire qui correspondait à l'espace alloué par malloc() alors que celui-ci n'est en rien lié à ton pointeur. Il t'est donc impossible de libérer cet espace et tu fais face à une fuite de mémoire. Et puisque tu as perdu son adresse, tu ne peux pas l'utiliser non plus.

  9. #9
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2013
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2013
    Messages : 10
    Par défaut
    Ok je vais donc pas passer par des mallocs et faire quelques expériences dans le main: j'ai modifié ma fonction explode pour quelle m'affiche la valeur du tableau qu'elle retourne:

    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
     
    int* explode(char* stringToExplode, char separator, int width)
    {
        int i = 0;
        int * finalArray[width];
        int indicator = 0; 
        int buffer = 0;
        int cursor = 0;
        int length = strlen(stringToExplode);
        for (i = 0;i < length;i++)
        {
            if ( stringToExplode[i] == separator && indicator == -1)
                {
                    finalArray[cursor] = buffer;
                    cursor++;
                    indicator = 0;
                    buffer =  0;
                }
            else if ( stringToExplode[i] != separator && stringToExplode[i] != '\n')
                {
                    buffer = buffer * 10 + (stringToExplode[i] - 48);
                    indicator = -1;
                }
        }
        finalArray[cursor] = buffer; 
        // Visualisation
        for (i = 0; i < width; i++)
        {
            printf("%d|",finalArray[i]);
        }
        printf("\n");
        return finalArray;
    }
    Elle écrit bien les bonnes valeurs du tableau soit :
    0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1|0|1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        printf("%d", explode("0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1", ' ', c)[0]); //on devrais voir la troisième case donc 0 dans les faits il me retourne 0
        printf("\n");
        printf("%d", explode("0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1", ' ', c)[1]); // on devrais voir la troisième case donc 0 dans les faits il me retourne 0
        printf("\n");
        printf("%d", explode("0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1  0  1", ' ', c)[2]); //on devrais voir la troisième case donc 0 dans les faits il me retourne 1

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

Discussions similaires

  1. Mettre un fichier csv dans un tableau à deux dimensions
    Par neeux dans le forum Général Python
    Réponses: 5
    Dernier message: 05/03/2007, 16h36
  2. Réponses: 6
    Dernier message: 25/02/2007, 17h56
  3. Réponses: 9
    Dernier message: 05/01/2007, 20h04
  4. Rechercher dans un tableau deux dimensions
    Par angelevil dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 28/09/2006, 20h29
  5. tri alphabétique dans un tableau deux dimensions
    Par *!!cocco!!* dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 06/12/2004, 21h38

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