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 :

Manipulation d'un tableau de pointeurs


Sujet :

C

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 7
    Points : 8
    Points
    8
    Par défaut Manipulation d'un tableau de pointeurs
    Bonjour,

    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
    #include <stdio.h>
     
    void addValue(char *pTab[], int length, char ajout[]) {
    	/* cette fonction ajoute une nouvelle valeur en fin de liste d'un tableau*/
    	int i=0;
    	char *nTab[length+1];
     
    	for (i=0; i < length; i++) {
    		nTab[i] = pTab[i];
    	}
     
    	nTab[length] = ajout;
    	pTab = nTab;
    }
     
    int main(int argc, char** argv)
    {
    	char *pItem[] = { /* initialisation du tableau de pointeurs */
    		"bijoux",
    		"chambre",
    		"mobilier",
    		"montagne",
    		"lit",
    	};
    	int length = 5;
    	char ajout[] = "fusil";
    	addValue(pItem, length, ajout);
     
    	printf("%s\n", pItem[6]);
     
    	return 0;
    }
    dans ce petit programme je représente un tableau de chaînes par un tableau, à une dimension, de pointeurs (afin d'optimiser l'occupation de la mémoire). Cependant je n'arrive pas à le manipuler en l'envoyant à une fonction. Ainsi l'instruction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%s\n", pItem[6]);
    renvoit des symboles incompréhensibles... Existe-t-il une solution ?

    Merci d'avance

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    2 grosses erreurs

    1) ta variable "ntab" se trouve être une variable locale à la fonction. Quand ton programme quitte la fonction, l'espace utilisé par la variable est réaffecté par le programme pour autre chose. Sauf que toi, cet espace tu le récupères par recopie dans un autre tableau dans le but de t'en servir. Tu t'en serviras, certes, mais il y aura toujours n'importe quoi et tu risques même d'écraser un truc utile par ailleurs

    2) ta recopie ntab=ptab ne recopie que les adresses, non les contenus. Donc le contenu est maintenant accessible par 2 points d'accès mais il reste unique
    Exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    char a[]="toto";
    char *b;
     
    b=a;
    a[1]='i';
    printf("%s\n", b)   => affichera "tito" alors que c'est a qui a été modifié
    Règle de base: on ne peut agrandir que ce qui a été alloué en mémoire vive par malloc. On peut alors utiliser realloc() qui se charge lui-même d'agrandir la zone allouée et recopie les datas si la nouvelle zone se trouve ailleurs que l'ancienne

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <stdio.h>
    #include <stdlib.h>
     
    int main()
    {
    	char** tab;		// Une zone qui stockera "n" pointeurs
    	int i;
     
    	char *bidon;		// Une zone bidon
     
    	// Allocation initiale
    	tab=(char **)malloc(5 * sizeof(char *));
     
    	// On remplit le tableau avec des adresses prises dans la mémoire statique du code
    	tab[0]="Hello_0";
    	tab[1]="Hello_1";
    	tab[2]="Hello_2";
    	tab[3]="Hello_3";
    	tab[4]="Hello_4";
     
    	// Ces chaines ne sont pas recopiées, seules leurs adresses l'est
    	// On affiche tout ça (l'indice, l'adresse de l'élément du tableau et son contenu
    	for (i=0; i < 5; i++)
    		printf("i=%d adr=0x%04x - [%s]\n", i, &tab[i], tab[i]);
     
    	// On alloue une zone bidon pour bouffer de la mémoire
    	bidon=(char*)malloc(1024 * 1024 * 1024);
     
    	// On agrandit le tableau mais on demande beaucoup plus
    	tab=(char **)realloc(tab, 7 * 1024 * 1024 * sizeof(char *));
    	printf("\n");
     
    	// On lui donne donc 2 autres pointeurs à stocker
    	tab[5]="Hello_5";
    	tab[6]="Hello_6";
     
    	// On réaffiche le tableau
    	for (i=0; i < 7; i++)
    		printf("i=%d adr=0x%04x - [%s]\n", i, &tab[i], tab[i]);
    }
    Résultat
    i=0 adr=0x88cf008 - [Hello_0]
    i=1 adr=0x88cf00c - [Hello_1]
    i=2 adr=0x88cf010 - [Hello_2]
    i=3 adr=0x88cf014 - [Hello_3]
    i=4 adr=0x88cf018 - [Hello_4]

    i=0 adr=0x764d8008 - [Hello_0]
    i=1 adr=0x764d800c - [Hello_1]
    i=2 adr=0x764d8010 - [Hello_2]
    i=3 adr=0x764d8014 - [Hello_3]
    i=4 adr=0x764d8018 - [Hello_4]
    i=5 adr=0x764d801c - [Hello_5]
    i=6 adr=0x764d8020 - [Hello_6]

    Comme tu peux le voir, le tableau a été placé ailleurs. Mais son contenu (les adresses des chaines "Hello...") ont été recopiées...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Je n'ai pas trouvé le problème de tête... :s
    Mais j'ai vu plusieurs problème:

    Il existe une fonction appelée realloc, qui peut vous être utile, dans le sens évite la recopie à la main, des éléments du tableaux, dans un autre tableaux. En fait, évite la création d'un tableau temporaire.

    Votre application se veut économe en mémoire, certes, mais vous avez des fuites de mémoires partout.
    Il manque des free().

    [EDIT] Me suis fait totallement grillée ( avec quelqu'un qui répond au problème )[/EDIT]
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 7
    Points : 8
    Points
    8
    Par défaut
    Merci à Sve@r et à LittleWhite. J'ai pu résoudre mon problème grâce à vous

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    [EDIT] Me suis fait totallement grillée ( avec quelqu'un qui répond au problème )[/EDIT]
    Arf, ça arrive. surtout quand la rédaction est longue. J'ai gagné hier... mais tu gagneras demain

    Citation Envoyé par LittleWhite Voir le message
    Votre application se veut économe en mémoire, certes, mais vous avez des fuites de mémoires partout.
    Il manque des free().
    Pas dans l'exemple initial de Stalko. Il n'y a pas de malloc donc pas besoin de free.

    Dans mon exemple, je suis d'accord. Mais c'était un exemple destiné à expliquer le mécanisme de fonctionnement de realloc et non un exemple destiné à enseigner la bonne façon d'allouer de la mémoire (et la libérer ensuite). On peut rajouter que dans mon exemple il manque aussi les tests d'allocation réussie. Et (pour Stalko), ces 2 éléments sont obligatoires quand on fait du malloc/realloc...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Tableau de pointeurs sur objets
    Par bassim dans le forum C++
    Réponses: 11
    Dernier message: 13/12/2005, 19h45
  2. [GCC] Tableau de pointeurs pour accès multiples en asm
    Par Flo. dans le forum x86 32-bits / 64-bits
    Réponses: 2
    Dernier message: 12/12/2005, 08h47
  3. Réponses: 1
    Dernier message: 27/11/2005, 14h30
  4. tableau de pointeurs
    Par seal3 dans le forum C++
    Réponses: 7
    Dernier message: 01/11/2005, 20h51
  5. Tableau de pointeurs de fonctions
    Par Alp dans le forum C++
    Réponses: 7
    Dernier message: 29/10/2005, 13h19

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