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 sur un tableau de structures


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 82
    Points : 54
    Points
    54
    Par défaut Pointeur sur un tableau de structures
    Bonjour,

    Un problème que je n'arrive jamais à résoudre, alors cette fois-ci au lieu de trouver des méthodes détournées pour essayer de passer outre ce problème, je vais l'aborder de plein fouet.

    Mais j'ai beau réfléchir, je n'y comprends pas grand chose, et j'aurai besoin d'un peu d'aide pour faire les choses correctement.

    Mon problème :

    Je déclare une structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
     
    	TCHAR *parametre1;             
    	TCHAR *parametre2;         
     
    } MaStr;
    Je déclare ensuite un tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaStr *tableau = new MaStr[MAX_STRUCT];
    J'ai ensuite une fonction qui est chargée de remplir ce tableau.
    Donc je dois passer en paramètre de ma fonction un pointeur sur mon tableau. ( si je ne me trompe pas? )

    voici le prototype de ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int MaFonction( MaStr *(tableau)[MAX_STRUCT] );
    Et l'appel :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaFonction( &tableau );
    Le problème se situe au niveau du passage en paramètre je pense. Car dans le corps de ma fonction, si j'utilise le pointeur, le programme compile mais plante.

    Ma conclusion c'est donc que le pointeur a une mauvaise valeur. Du coup je tape dans un espace mémoire réservé... Pourtant je ne vois pas mon erreur.

    Merci d'avance pour ceux qui pourront m'aider

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    le prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int MaFonction( MaStr *tableau);
    l'appel :

    Tout simplement (ou alors, j'ai pas bien compris)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 603
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 603
    Points : 17 913
    Points
    17 913
    Billets dans le blog
    2
    Par défaut
    d'une part que vient faire ce "new" ?? Tu programmes en C++ ??


    Une manière normale en C serait :

    soit

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    MaStr tableau[MAX_STRUCT];

    soit

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    MaStr *tableau= malloc(MAX_STUCT*sizeof(MaStr)) ;


    Ensuite, c'est simple :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int MaFonction ( MaStr **table) 
    {
    ..
    }
     
     
     i = MaFonction ( &tableau);

    Qui ne marche que dans le 2ième cas (alocation).

    Si tu dimensionnes réellement , alors c'est :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int MaFonction ( MaStr *table) 
    {
    ..
    }
     
     
     i = MaFonction ( tableau);
    "Un homme sage ne croit que la moitié de ce qu’il lit. Plus sage encore, il sait laquelle".

    Consultant indépendant.
    Architecture systèmes complexes. Programmation grosses applications critiques. Ergonomie.
    C, Fortran, XWindow/Motif, Java

    Je ne réponds pas aux MP techniques

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 82
    Points : 54
    Points
    54
    Par défaut
    Ça ne marche toujours pas.

    J'ai utilisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    MaStr *tableau= malloc(MAX_STUCT*sizeof(MaStr)) ;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    int MaFonction ( MaStr **table) 
    {
    ..
    }
     
     
     i = MaFonction ( &tableau);
    Et lorsque je fais dans le corps de ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    wcscpy_s( (wchar_t *)*(tableau)[index]->parametre1, sizeof(buffer), buffer ); // bug ici
    Ça compile correctement, mais le programme plante à l'exécution.

    A noter la modification suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    typedef struct {
     
    	TCHAR parametre1[MAX_LENGHT];             
    	TCHAR parametre2[MAX_LENGHT];         
     
    } MaStr;
    Il me semble avoir tout essayé, et j'ai plus d'idée sur l'origine du problème.

  5. #5
    Rédacteur
    Avatar de Neitsa
    Homme Profil pro
    Chercheur sécurité informatique
    Inscrit en
    Octobre 2003
    Messages
    1 041
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chercheur sécurité informatique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 041
    Points : 1 956
    Points
    1 956
    Par défaut
    Un exemple:

    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
     
    #define MAX_LENGTH 256
    #define MAX_STRUCT 100
     
    CONST TCHAR s1[] = _T("SENTENCE 1");
    CONST TCHAR s2[] = _T("SENTENCE 2");
     
    typedef struct {
     
    	TCHAR parametre1[MAX_LENGTH];             
    	TCHAR parametre2[MAX_LENGTH];         
     
    } MASTR;
     
     
    void foo(MASTR* tab)
    {
    	int i = 0;
    	for(i = 0; i < MAX_STRUCT; i++)
    	{
    		_tcscpy_s(tab[i].parametre1, MAX_LENGTH, s1);
    		_tcscpy_s(tab[i].parametre2, MAX_LENGTH, s2);
    	}
    }
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	MASTR* tab = (MASTR*) malloc(MAX_STRUCT * sizeof(MASTR));
     
    	foo(tab);
     
    	free(tab);	
     
    	return 0;
    }

    Le problème avec les tableaux de taille fixe (MAX_LENGTH) c'est qu'on perd une place folle si les chaînes sont plus courtes. Je ferais plutôt de façon à allouer à chaque fois la bonne taille.

    L'inconvénient, dans ce dernier cas de figure, est que le code devient plus "complexe" étant donné qu'il faudra allouer et libérer pour chaque structure plutôt que globalement.

    Petites remarques:

    wcscpy(), c'est pour le type wchar_t, pas pour le type TCHAR (qui peut désigner soit des des caractères Unicode, soit MBCS).

    Même chose pour le cast en wchar_t plutôt dangereux si on est en MBCS.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Points : 1 750
    Points
    1 750
    Par défaut
    Ça compile correctement, mais le programme plante à l'exécution.
    Commençons déjà par une chose essentielle :
    Si ton "new" passait à la compilation, c'est que manifestement tu compiles non pas en C mais en C++. Configure déjà ton projet de manière à ce qu'il compile en C, car un code C doit être compilé avec un compilo C.

  7. #7
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int MaFonction ( MaStr **tableau) 
    {
     ....
    wcscpy_s( (wchar_t *)*(tableau)[index]->parametre1, sizeof(buffer), buffer ); // bug ici
    Le problème est sur l'argument *(tableau)[index]->parametre1 :

    1- on devrait avoir (*tableau) pour avoir un pointeur sur le tableau de MaStr

    2- Un élément de ce tableau est alors (*tableau)[index]

    3- Cet élément est une structure. Pour accéder à son membre parametre1 : (*tableau)[index].parametre1
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    82
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 82
    Points : 54
    Points
    54
    Par défaut
    En effet, je perds beaucoup de place, mais ça permet aussi de sécuriser mon application en évitant les chaines trop longues.

    De plus c'est une petite application, donc sauf si le PC date de 1995, donc la mémoire n'est pas trop mon soucis premier ici.

    Mais je note et je retiendrais pour une application plus gourmande.


    wcscpy(), c'est pour le type wchar_t, pas pour le type TCHAR (qui peut désigner soit des des caractères Unicode, soit MBCS).
    Tu as encore raison, mais comme je code en Unicode, TCHAR = wchar_t. Mais je devrais être plus rigoureux là dessus à l'avenir, merci du conseil.

    ( J'avoue que c'est un peux pénible leur trus TCHAR = wchar_t ou TCHAR = char* )

    Pour tout ceux qui m'ont fait la remarque pour les bouts de code C++, oui je code en C++.
    Je suis venu sur le forum C, car il me semble que se problème relevait d'avantage du C "pur" plutôt que d'un problème objet, ou inhérent au C++.
    Et je pense vraiment que le problème n'a rien à voir avec un mot clé C++ dans mon code, ou alors un compilo C++ qui serait ( je ne sais pas pourquoi ) incapable de compiler du C.


    Pour finir, merci à vous tous, et surtout à diogene qui m'a fourni la solution sur un plateau!

    Ça marche parfaitement.

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 13/11/2008, 21h28
  2. Réponses: 5
    Dernier message: 21/09/2008, 09h45
  3. Réponses: 8
    Dernier message: 17/09/2008, 12h11
  4. Réponses: 1
    Dernier message: 09/07/2006, 23h39
  5. Références et pointeurs sur un tableau
    Par smag dans le forum C++
    Réponses: 2
    Dernier message: 01/03/2005, 20h29

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