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 vers une structure a double pointeurs


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 37
    Billets dans le blog
    1
    Par défaut Pointeur vers une structure a double pointeurs
    salut
    je suis debutant en c et j'ai un problème avec mon code:

    utilitaire.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #ifndef UTILITAIRES_H
    #define UTILITAIRES_H
     
    typedef struct
    {
        int lignes;
        int colonnes;
        int** tb;
    }Tableau;
     
    Tableau *nouveau_tableau(int l,int c, int initialisation);
    void aff_tterrain(Tableau *tab, int lignes, int colonnes);
    #endif // UTILITAIRES_H
    utilitaire.c
    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
     
    #include "utilitaires.h"
    Tableau *nouveau_tableau(int l,int c, int initialisation){
            int i=0,j=0;
            Tableau *tab = NULL;
            tab->lignes = l;
            tab->colonnes = c;
            tab->tb=malloc(tab->lignes*sizeof(*tab->tb));
     
            if(tab->tb == NULL)
                exit(0);
            for(i; i<tab->lignes; i++){
                    tab->tb[i]=malloc(tab->colonnes*sizeof(*tab->tb[i]));
                    if(tab->tb[i]==NULL){
                        for(int p=i-1; p>=0; p--)
                            free(tab->tb[p]);
                    }
            }
            for(i; i<tab->lignes; i++){
                for(j; j<tab->colonnes; j++){
                    tab->tb[i][j]=initialisation;
                }
            }
            for(i; i<tab->lignes; i++){
               for(j; j<tab->colonnes; j++){
                   free(tab->tb[i][j]);
               }
           }
     
    return tab;
    }
     
    void aff_tterrain(Tableau *tab, int lignes, int colonnes){
     
        for(int i = 0; i < tab->lignes; i++){
            for(int j = 0; j < tab->colonnes; j++){
                if(tab->tb[i][j] >= 10)
                    printf(" %d |", tab->tb[i][j]);
                else
                     printf(" %d  |", tab->tb[i][j]);
            }
            printf("\n______________________________________________________\n");
        }
     
    }
    main.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
    #include <stdlib.h>
    #include "utilitaires.h"
    int main()
    {
        Tableau *carte = nouveau_tableau(10,5,0);
        aff_tterrain(carte,10,5);
        return 0;
    }
    le truc c'est qu'au moment de la compilation il y'a plantage et je ne comprend pas.
    j'ai d'abord testé la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int **nouveau_tableau(int l,int c, int initialisation){
    ...
    ...
    }
    ...qui marchait bien. mais je voudrais plutot fonctionner avec une structure que j'ai nommée "Tableau".
    quelqu'un peut-il-m'aider?
    merci d'avance

  2. #2
    Membre Expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    610
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2013
    Messages : 610
    Billets dans le blog
    21
    Par défaut
    En général on parle plus de plantage pendant l'exécution et d'erreur pendant la compilation...
    Que dit ton compilateur lorsqu'il refuse de compiler?

  3. #3
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 37
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par stendhal666 Voir le message
    En général on parle plus de plantage pendant l'exécution et d'erreur pendant la compilation...
    Que dit ton compilateur lorsqu'il refuse de compiler?
    ah oui c'est juste que j'utilise code::block et ça compile et exécute consécutivement.
    sinon le programme plante au moment de l'exécution. il y'a juste des avertissements pendant la compilation.

  4. #4
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Je pense que ta structure tableau est assez simple pour que tu puisses la créer par valeur, même si je conseillerais de la manipuler ensuite par pointeur.

    Ensuite, ta fonction nouveau_tableau() n'est pas censée utiliser free() hors des cas d'échec.

    Et aussi, faire moins d'allocations: Une allocation par dimension (en remplaçant double par int) suffit.

    Code C : 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
    Tableau Tableau_nouveau(int l, int c, int initialisation)
    {
    	Tableau ret = {0};
    	int x, y;
    	ret.lignes = l;
    	ret.colonnes = c;
    	ret.tb = AutreAllocTable2D(l, c);
     
    	for(y=0 ; y<l ; y++)
    	{
    		for(x=0 ; x<c ; x++)
    			ret.tb[y][x] = initialisation;
    	}
    }
    void Tableau_destruction(Tableau*tab)
    {
    	AutreFreeTable2D(tab->tb);
    	tab->tb = NULL;
    	tab->lignes = 0;
    	tab->colonnes = 0;
    }
     
    int Tableau_get(Tableau *tab, int l, int c)
    {
    	if(tab==NULL || tab->tb==NULL || l<0 || l >= tab->lignes || c<0 || c >= tab->colonnes)
    	{
    		/*Erreur! Faire quelque chose?*/
    	}
    	return tab->tb[l][c];
    }
    void Tableau_set(Tableau *tab, int l, int c, int valeur)
    {
    	if(tab==NULL || tab->tb==NULL || l<0 || l >= tab->lignes || c<0 || c >= tab->colonnes)
    	{
    		/*Erreur! Faire quelque chose?*/
    	}
    	tab->tb[l][c] = valeur;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 37
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Je pense que ta structure tableau est assez simple pour que tu puisses la créer par valeur, même si je conseillerais de la manipuler ensuite par pointeur.

    Ensuite, ta fonction nouveau_tableau() n'est pas censée utiliser free() hors des cas d'échec.

    Et aussi, faire moins d'allocations: Une allocation par dimension (en remplaçant double par int) suffit.

    Code C : 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
    Tableau Tableau_nouveau(int l, int c, int initialisation)
    {
    	Tableau ret = {0};
    	int x, y;
    	ret.lignes = l;
    	ret.colonnes = c;
    	ret.tb = AutreAllocTable2D(l, c);
     
    	for(y=0 ; y<l ; y++)
    	{
    		for(x=0 ; x<c ; x++)
    			ret.tb[y][x] = initialisation;
    	}
    }
    void Tableau_destruction(Tableau*tab)
    {
    	AutreFreeTable2D(tab->tb);
    	tab->tb = NULL;
    	tab->lignes = 0;
    	tab->colonnes = 0;
    }
     
    int Tableau_get(Tableau *tab, int l, int c)
    {
    	if(tab==NULL || tab->tb==NULL || l<0 || l >= tab->lignes || c<0 || c >= tab->colonnes)
    	{
    		/*Erreur! Faire quelque chose?*/
    	}
    	return tab->tb[l][c];
    }
    void Tableau_set(Tableau *tab, int l, int c, int valeur)
    {
    	if(tab==NULL || tab->tb==NULL || l<0 || l >= tab->lignes || c<0 || c >= tab->colonnes)
    	{
    		/*Erreur! Faire quelque chose?*/
    	}
    	tab->tb[l][c] = valeur;
    }
    merci pour la reponse mais un souci au niveau de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ret.tb = AutreAllocTable2D(l, c);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AutreFreeTable2D(tab->tb);
    je suppose qu'il faut écrire ces fonctions à part...comment les ecrire correctement? Et le fait de manipuler par valeur une structure contenant un pointeur ne serait pas risqué? a chaque fois que je l'ai essayé j'ai obtenu cette erreur en compilant:
    error: subscripted value is neither array nor pointer nor vector

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Citation Envoyé par pal1996 Voir le message
    merci pour la reponse mais un souci au niveau de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ret.tb = AutreAllocTable2D(l, c);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AutreFreeTable2D(tab->tb);
    je suppose qu'il faut écrire ces fonctions à part...comment les ecrire correctement? Et le fait de manipuler par valeur une structure contenant un pointeur ne serait pas risqué? a chaque fois que je l'ai essayé j'ai obtenu cette erreur en compilant:
    error: subscripted value is neither array nor pointer nor vector
    Il y avait un lien dans mon message: ici. Note par contre, qu'elle avait été écrite pour un tableau de double (mais comme indiqué, normalement il suffit de remplaçer double par int... l'inverse n'aurait pas forément été vrai)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 37
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Il y avait un lien dans mon message: ici. Note par contre, qu'elle avait été écrite pour un tableau de double (mais comme indiqué, normalement il suffit de remplaçer double par int... l'inverse n'aurait pas forément été vrai)
    j'ai appris beaucoup de choses que j'ignorais jusqu'ici avec ton lien (et je te remerci pour cela). Mais seulement mon vrai probleme n'est pas encore résolu. En fait dans le code que j'ai envoyé que tu as édité j'ai comme l'impression que les lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ret.tb = AutreAllocTable2D(l, c);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ret.tb[y][x] = initialisation;
    ...ne se comprennent pas entre-elles et il en ressort l'erreur de compilation que j'ai citée précedemment à savoir "souscripted value is neither array nor pointer nor vector". Et je me pose la question de savoir s'il n'est pas préférable de manipuler la stucture par pointeur plutôt que par valeur pour éviter cela; et si c'est le cas, peux-tu m'aider?

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 398
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 398
    Par défaut
    Citation Envoyé par pal1996 Voir le message
    j'ai appris beaucoup de choses que j'ignorais jusqu'ici avec ton lien (et je te remerci pour cela). Mais seulement mon vrai probleme n'est pas encore résolu. En fait dans le code que j'ai envoyé que tu as édité j'ai comme l'impression que les lignes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ret.tb = AutreAllocTable2D(l, c);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ret.tb[y][x] = initialisation;
    ...ne se comprennent pas entre-elles et il en ressort l'erreur de compilation que j'ai citée précedemment à savoir "souscripted value is neither array nor pointer nor vector". Et je me pose la question de savoir s'il n'est pas préférable de manipuler la stucture par pointeur plutôt que par valeur pour éviter cela; et si c'est le cas, peux-tu m'aider?
    Bizarre... tb est-il bien déclaré comme int**?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Deux soucis dans nouveau_tableau :
    • elle déclare Tableau *tab = NULL; puis accède aux membres de tab ;
    • elle libère les colonnes qu'elle alloue (erreur similaire à ce post récent). En général la présence d'un free dans une fonction d'initialisation doit te mettre la puce à l'oreille.


    Je me permets de te donner un autre conseil, utilise un tableau unidimensionnel pour stocker ta matrice, par exemple :
    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
    Tableau *Tableau_alloc(int lig, int col) {
        Tableau *tab = malloc(sizeof(Tableau));
        if (!tab)
            goto end;
     
        tab->lignes = lig;
        tab->colonnes = col;
        tab->tb = malloc(lig * col * sizeof(int));
        if (!tab->tb) {
            free(tab);
            tab = NULL;
        }
     
    end:
        return tab;
    }
     
    int *Tableau_get_at(Tableau *tab, int x, int y) {
        return &tab->tb[x + y * tab->lignes];
    }
    Ça retirera un niveau de complexité inutile - selon moi - à ton programme.


    Pour définir une telle structure, j'aurais personnellement tendance à utiliser cette construction disponible depuis C99 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct {
        unsigned int w, h;
        int data[];
    } matrix;
    Mais l'allocation en est encore un peu complexe pour un débutant, on verra cela un autre jour.

    EDIT : grillé.

  10. #10
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 37
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Deux soucis dans nouveau_tableau :
    • elle déclare Tableau *tab = NULL; puis accède aux membres de tab ;
    • elle libère les colonnes qu'elle alloue (erreur similaire à ce post récent). En général la présence d'un free dans une fonction d'initialisation doit te mettre la puce à l'oreille.
    Les colonnes sont libérées sous une condition donc je vois pas ce qu'il y'a de grave!
    Et pour le tableau à une dimension je crois pas que cela sera facilement gérable au moment d'utiliser la fonction.

    Citation Envoyé par Matt_Houston Voir le message
    Mais l'allocation en est encore un peu complexe pour un débutant, on verra cela un autre jour.

    EDIT : grillé.
    C'est un devoir et je n'ai plus beaucoup de temps. Pour l'instant c'est l'unique fonction qui m'empeche de continuer mon travail.
    Et merci pour ton apport! j'en apprend beaucoup.

  11. #11
    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 pal1996 Voir le message
    Les colonnes sont libérées sous une condition donc je vois pas ce qu'il y'a de grave!
    Lignes 24 à 28 d'utilitaire.c, je n'y vois pas de condition !

    Citation Envoyé par pal1996 Voir le message
    Et pour le tableau à une dimension je crois pas que cela sera facilement gérable au moment d'utiliser la fonction.
    C'est toi qui voit, fais ce avec quoi tu es le plus à l'aise.


    Citation Envoyé par pal1996 Voir le message
    C'est un devoir et je n'ai plus beaucoup de temps. Pour l'instant c'est l'unique fonction qui m'empeche de continuer mon travail.
    Et merci pour ton apport! j'en apprend beaucoup.
    Bien entendu, raison pour laquelle je ne me suis pas étendu sur le sujet. Ce sera pour une prochaine fois.

  12. #12
    Membre averti

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2015
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2015
    Messages : 37
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Lignes 24 à 28 d'utilitaire.c, je n'y vois pas de condition !)
    ah oui t'as raison je voiyais plutôt les lignes précédentes. Ces dernières lignes ne devraient même pas se trouver dans la fonction comme tu l'a si bien dit. Merci.

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 28/03/2014, 09h56
  2. Réponses: 2
    Dernier message: 15/02/2011, 10h34
  3. Utilité d'un pointeur vers une fonction ?
    Par Nasky dans le forum C
    Réponses: 10
    Dernier message: 20/03/2010, 19h54
  4. Réponses: 67
    Dernier message: 13/02/2007, 18h08
  5. pointeur vers une structure
    Par Xyrroa dans le forum C
    Réponses: 14
    Dernier message: 12/04/2006, 13h13

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