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

DJfewos971 Messages postés 4 Date d'inscription dimanche 26 septembre 2004 Statut Membre Dernière intervention 13 février 2009 - 12 févr. 2009 à 23:24
Arwen29 Messages postés 1 Date d'inscription jeudi 10 avril 2003 Statut Membre Dernière intervention 17 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!!

6 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 14
12 févr. 2009 à 23:57
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.
0