Allocation dynamique de mémoire d'un tableau dans une fonction
DJfewos971
Messages postés4Date d'inscriptiondimanche 26 septembre 2004StatutMembreDernière intervention13 février 2009
-
12 févr. 2009 à 23:24
Arwen29
Messages postés1Date d'inscriptionjeudi 10 avril 2003StatutMembreDernière intervention17 janvier 2010
-
17 janv. 2010 à 16:32
Bonjour a tous,
mon problème est de pouvoir alloué la mémoire dynamiquement d'un tableau dans une fonction.
Voici mon problème niveau Code:
#include <stdio.h>
#include <stdlib.h>
#include "tri.h"
int main()
{
int i= 5;
int *tab;
initialiserTableau(tab,i);
printf("%d-%d\n",tab[1],tab[2]);
}
int initialiserTableau (int* tab, int n)
{
tab = (int *) calloc( n,sizeof(int));
tab[1]=2;
tab[2]=0;
printf("%d-%d\n",tab[1],tab[2]);
}
le tableau fait donc partie de la fonction main, puis l'allocation mémoire se fait dans la fonction initiliserTableau.
le problème est que lor du retour dans le main, le tableau ne possède pas les mêmes valeurs. Si quelqu'un a une idéé comment faire SVP??
Merci à tous!!
A voir également:
Allocation dynamique tableau 2d c
Tableau dynamique c - Meilleures réponses
Allocation dynamique tableau c++ - Meilleures réponses
Tel qu'est ton code, tu déclares un int* dans ton main comme variable locale. Donc lors de l'exécution du main, un pointeur va être alloué (C'est plus une réservation qu'une allocation en fait) dans la pile (Sans initialisation de ce pointeur).
Puis tu appelles initialiserTableau en lui passant ce pointeur. En fait, tu lui passes une copie de ce pointeur non initialisé. Tu lui passe une adresse invalide en entrée.
Dans initialiserTableau, tu affectes ton argument, c'est à dire la copie du pointeur, avec une zone allouée avec calloc. En sortie de fonction, la copie est "supprimée", et tu perd l'adresse de ton tableau que tu ne peux plus libérer. Et quand ensuite tu testes ton tableau dans le main, tu regardes à une adresse qui n'a pas été initialisée. Passée par copie à initialiserTableau, elle n'a pas changée de valeur depuis le début du main.
Il faut que tu passe l'adresse du pointeur de ton main. (Ca à l'air lourd comme ça, mais quand tu auras compris, tu fera tout ça naturellement).
Il faut que ta fonction initialiser tableau prenne en argument un int**. Dans le main, tu passeras non pas ton pointeur, mais l'adresse de ton pointeur : &tab. Et lors de l'affectation à partir de calloc et de la manipulation, il faudra que tu déréférence ton pointeur (*tab).
Autre remarque, plus sur ton algo... On cherche souvent à éviter le principe de l'allocation dynamique réalisée par l'appelée. En général, c'est l'appelante qui alloue. Et si possible dans la pile (int tab[50]), pour de meilleurs perfs. Cela permet à l'appelante de gérer la mémoire de bout en bout : si on fait une allocation dynamique, on est sûr qu'il va falloire la libérer. Dans ton cas, on risque d'oublier la libération plus facilement. Reste que l'appelante ne sais pas forcément de combien de mémoire à besoin l'appelée... Dans ces cas là on fait comme tu as essayé de faire, ou on utilise un code d'erreur pour demander un nouvel appel avec un tampon plus gros, ou on propose un moyen de récupérer la taille nécessaire avant d'appeler la fonction.
Dernière remarque, compile avec les warnings si possible et occupe t'en. Au moins -Wall si tu utilises gcc. Il te dira notamment que ton main ne renvoie pas de valeur alors qu'il devrait renvoyer un int, le code de retour de ton programme.
DJfewos971
Messages postés4Date d'inscriptiondimanche 26 septembre 2004StatutMembreDernière intervention13 février 2009 13 févr. 2009 à 00:39
Bonsoir rt15, Merci de ta réponse.
Il est vrais que mon code n'est pas tout à fait correct, mais disont que ce n'est qu'un petit bout de code expliquant mon problème. mais tu as raison, soyons rigoureux.
j'utilise bien GCC (sur débian). j'avais aussi pensé à utiliser le pointeur d'un pointeur (int**) puis mettre ladresse de mon pointeur (&tab) lors de l'appel à la fonction, mais gcc me génére une erreur.
04
05 int main()
06 {
07 int i= 5;
08 int * tab;
09 initialiserTableau(&tab,i);
10 printf("%d-%d\n",tab[1],tab[2]);
11 free (tab);
12 return 0;
13 }
14
15 void initialiserTableau (int** tab, int n)
16 {
17 tab = (int *) calloc( n,sizeof(int));
18 tab[1]=2;
19 tab[2]=0;
20 printf("%d-%d\n",tab[1],tab[2]);
21 }
Voici les erreurs généré par GCC:
$ gcc tri.c -o tri
tri.c: In function ‘main’:
tri.c:9: warning: passing argument 1 of ‘initialiserTableau’ from incompatible pointer type
tri.c: At top level:
tri.c:14: error: conflicting types for ‘initialiserTableau’
tri.h:3: error: previous declaration of ‘initialiserTableau’ was here
tri.c: In function ‘initialiserTableau’:
tri.c:16: warning: assignment from incompatible pointer type
tri.c:17: warning: assignment makes pointer from integer without a cast
Peut être y a t'il quelque chose qui m'ait échapé? ps: Ce code n'a pas de but particulier, c'est juste pour le sport. je suis tombé sur ce problème et je voudrais réussirà le résoudre.
Sinon tu me disais que dans la pratique, on dimensionne le tableau dans la fonction principale plutot que d'appeler une fonction qui elle dimensionne le tableau. Je prends note.
int main()
{
int i= 5;
int * tab;
initialiserTableau(&tab,i);
printf("%d-%d\n",tab[1],tab[2]);
free (tab);
return 0;
}
int initialiserTableau (int** tab, int n)
{
tab = (int **) calloc( n,sizeof(int));
*tab[1]=2;
*tab[2]=0;
printf("%d-%d\n",tab[1],tab[2]);
}
cette fois ci je compile, mais l'ors de l'execution j'ai le droit à un segmentation default. On m'avait dis que ce genre d'erreur est provoqué l'orsque l'on tente de lire une zone mémoire dont notre processus n'a pas accées.
je pense m'approcher du but. je tiens au courant de mes évolutions. Si quelqu'un a d'autres idéés, qu'il n'hésite pas. bonne soirée!
Vous n’avez pas trouvé la réponse que vous recherchez ?
Pistol_Pete
Messages postés1053Date d'inscriptionsamedi 2 octobre 2004StatutMembreDernière intervention 9 juillet 20137 13 févr. 2009 à 09:05
Salut
Tu alloues des int et pas des pointeurs sur des int! Donc il ne faut qu'une étoile pour le calloc.
Il faut faire aussi attention aux parenthèses qui sont ici indispensables...
(*tab)= (int* ) calloc( n,sizeof(int));
(*tab)[1]=2;
(*tab)[2]=0;
printf("%d-%d\n",(*tab)[1],(*tab)[2]);
A+
____________________________________________________________________________
Mon site internet :
http://ImAnalyse.free.fr
Arwen29
Messages postés1Date d'inscriptionjeudi 10 avril 2003StatutMembreDernière intervention17 janvier 2010 17 janv. 2010 à 16:32
Aaah! Merci, enfin un exemple clair et simple!
J'avais le même souci que DJfewos971, mais avec une chaîne de caractères.
Au cas où ça en aiderait certains, voici mon code (très légèrement) adapté: