begin process at 2012 05 28 07:20:49
  Trouver un code source :
 
dans
 
Accueil > Forum > 

C

 > 

Divers

 > 

Général

 > 

Allocation dynamique de mémoire d'un tableau dans une fonction


Derniers messages déposésPoser une question dans le forum ou lancer une discussion

Allocation dynamique de mémoire d'un tableau dans une fonction

jeudi 12 février 2009 à 23:24:12 | Allocation dynamique de mémoire d'un tableau dans une fonction

DJfewos971

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!!
jeudi 12 février 2009 à 23:57:58 | Re : Allocation dynamique de mémoire d'un tableau dans une fonction

rt15

Membre Club Administrateur CodeS-SourceS
Bienvenue !

Avant tout, une remarque sur ton code : tu ne libères pas ton tableau alloué avec calloc. Il faut que tu utilises free.

Pour ta question...

Il faut que tu travaille tes pointeurs.

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.
vendredi 13 février 2009 à 00:39:14 | Re : Allocation dynamique de mémoire d'un tableau dans une fonction

DJfewos971

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.

voici le code rectifié:

01 #include <stdio.h>
02 #include <stdlib.h>
03 #include "tri.h"

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.

Merci encore!
vendredi 13 février 2009 à 00:43:55 | Re : Allocation dynamique de mémoire d'un tableau dans une fonction

DJfewos971

PS: j'ai fait une petite erreur, l'erreur de la ligne 14 concerne la ligne 15, et les warning 16 et 17 font référence aux lignes 17 et 18
vendredi 13 février 2009 à 00:56:35 | Re : Allocation dynamique de mémoire d'un tableau dans une fonction

DJfewos971

Pardon, j'ai répondu trop vite. je n'avais pas mis à jour le fichier .h

voici donc la véritable version du source:

#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]);
  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!
vendredi 13 février 2009 à 09:05:51 | Re : Allocation dynamique de mémoire d'un tableau dans une fonction

Pistol_Pete

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 :
  
[ Lien ]

dimanche 17 janvier 2010 à 16:32:58 | Re : Allocation dynamique de mémoire d'un tableau dans une fonction

Arwen29

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é:
Code C/C++ :
void initialiserTableau (char** tab, int n)
{
    (*tab)= (char**) calloc( n,sizeof(char));
    (*tab)[0]='A';
    (*tab)[1]='B';
    (*tab)[2]='C';
    (*tab)[3]='D';
    (*tab)[4]='\0';
    printf("inside: %c-%c\n",(*tab)[1],(*tab)[2]);

}

int main()
{
  int i=5;
  char *tab;
  initialiserTableau(&tab,i); 
  printf("%s\n",tab);
  free (tab);
  return 0;
}


Voilà, ce qui m'a permis par la suite de faire une fonction de copie de chaînes.
Bonne journée à tous!


Cette discussion est classée dans : fonction, int, tableau, tab, mémoire


Répondre à ce message

Sujets en rapport avec ce message

Allocation dynamique dans une fonction [ par Veovis ] Salut,Toujours dans mon projet de TP, j'ai un petit soucis avec l'allocation dynamique dans une fonction. Ce que je voudrais faire c'est quand le tabl Tableau en C [ par Mickylord ] Bonsoir a tous !Voici ma question :J'ai une fonction principale, main(), et une autre fonction tab(). Je voudrais déclarer un tableau dans la fonction tableau d'entier. [ par gdpasmini ] Hello !j'ai un petit soucis avec une fonction qui renvoi un tableau en parametre... voila les details :Dans mes fonctions : int * boutonDecodFlux(void Exercice sur Pointeurs, classes, héritage... [ par snoozriton ] Bonjour à tous, étant en train d'étudier le C++, j'ai quelques soucis avec un exercice. C'est un classique dont je vous donne l'énoncé : [b]1. Défini pile dynamique [ par korin221 ] Bonjour! Voila j'ai un problème. Je voudrais mélanger ma pile dynamique de façon aléatoire. Peut on directement mélanger la pile ou alors passer la pi Probleme passage tab** de fonctions a fonction. [ par Nitrakz ] Bonjour tous le monde ! Comme l'explique le titre j'ai un petit soucis pour passer un tableaux a 2 dimensions tab[i][j] d'une fonction a une autre. Problème de définition de fonction dans une classe [ par labuche75 ] Bonjour à tous, je rencontre un problème à priori de définition de fonction dans la classe tableau permettant de manipuler de grands entiers nécessair passage de tableau à 3 dimensions en paramètre à une fonction [ par snake57 ] Bonjour à tous, J'ai un tableau à 3 dimensions que je veux afficher à partir d'une fonction. J'ai donc créé une fonction mais celle-ci affiche...n'im remplir un nombre dans un tableau [ par alex934 ] Bonjour, j'ai besoin de votre aide :) Voila je souhaite mettre un nombre stocké(int) dans un tableau exemple: int a=132; int tab[3]; je voudrais tableau dans une fonction [ par meksoft002 ] salut, je vouderais mettre la dimension d'un tableau a partir d'une fonction mais..l'éxecution ne se termine pas quand je la lance void creer(Personn


Nos sponsors


Sondage...

Comparez les prix

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,515 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales