Gestion dymamique de la taille d'un tableau de pointeurs [Résolu]

Signaler
Messages postés
50
Date d'inscription
jeudi 17 novembre 2005
Statut
Membre
Dernière intervention
7 janvier 2009
-
Messages postés
50
Date d'inscription
jeudi 17 novembre 2005
Statut
Membre
Dernière intervention
7 janvier 2009
-
La taille d'un tableau de char lors de la déclaration est
char * TAB[5];

Comment en cours du programme augmenter la taille de TAB.
Je n'arrive pas a utiliser realloc

merci

Timy94</gras>

8 réponses

Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Impossible justement. C'est un tableau. Sa taille est fixe. Il faut déclarer un pointeur de pointeur.

char **TAB;

L'inconvénien c'est que tu devra allouer pour, chaque pointeur, sa mémoire dynamiquement (avec malloc ou autre).

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Si ça peut t'aider, j'avais fais des fonctions qui geraient
dynamiquement la mémoire de pointeur de pointeurs. Elles peuvent
probablement être améliorée:


void **malloc2d (int num, int size)

{

    void **tab (void**)malloc(sizeof(void*)*num), **c tab;


    while(num > 0)

    {

        *c = (void*)malloc(size);

        c++; num--;

    }


    return tab;

}


void free2d (void **tab, int num)

{

    void **c = tab;


    while(num > 0)

    {

        free(*c);

        c++; num--;

    }


    free((void*)tab);

}


Ça fontionne comme ça:


char **TAB;


TAB = (char**)malloc2d(2, 5); // 2 espaces mémoires contenant chacun 5 octets (puisqu'il s'agit ici de char)


...


free2d(TAB, 2); // Libération de la mémoire

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Son addresse est retourné et la mémoire est toujours alloué car à moin que je me trompe, c'est à ça que sers malloc. Elle est ensuite récupérer par TAB qui pointera donc sur la zone réservé par malloc.

D'ailleur, y'a encore des problèmes dans mes fonctions. Voici ENCORE une correction:

void **malloc2d (int num, int size)
{
    void **tab, **c;

    if(num <= 0 || size <= 0) return 0;
    tab (void**)malloc(sizeof(void*)*num); c tab;

    if(!c) return 0;

    while(num > 0)
    {
        *c = (void*)malloc(size);

        if(*c == 0)
        {
            while(c > tab)
            {
                c--; free(*c);
            }

            free((void*)tab);

            return 0;
        }           
        c++; num--;
    }

    return tab;
}

void **realloc2d (void **tab, int num, int newsize)
{
    void **d;

    if(tab == 0 || num <= 0 || newsize <= 0) return 0;

    d = tab;

    while(num > 0)
    {
        void *c = (void*)realloc(*d, newsize);

        if(!c)
        {
            while(d > tab)
            {
                free(*d); d--;
            }

            free((void*)tab);
        }
        *d = c; d++; num--;
    }

    return tab;
}

C++ (@++)<!--
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Orrrrffff décidément:

void **realloc2d (void **tab, int num, int newsize)
{
    void **d;

    if(tab = = 0 || num <= 0 || newsize <= 0) return 0;

    d = tab;

    while(num > 0)
    {
        void *c = (void*)realloc(*d, newsize);

        if(!c)
        {
            while(d > tab)
            {
                free(*d); d--;
            }

            free((void*)tab);

             return 0;
        }
        *d = c; d++; num--;
    }

    return tab;
}

C++ (@++)<!--
Messages postés
573
Date d'inscription
samedi 16 novembre 2002
Statut
Membre
Dernière intervention
9 avril 2008
1
void **malloc2d (int num, int size)
{
void **tab (void**)malloc(sizeof(void*)*num), **c tab;

while(num > 0)
{
*c = (void*)malloc(size);
c++; num--;
}

return tab;
}

Attention ta variable tab n'existe plus en dehors de la fonction ou elle est crée.
Il se peut que quelque chose soit écrit par dessus, et le programme plantera.
Messages postés
3212
Date d'inscription
lundi 7 novembre 2005
Statut
Membre
Dernière intervention
16 février 2009
15
Bon. J'ai fais à la va vite une fonction de réallocation qui permet de
redéfinir la taille de tout les pointeurs pointé et apporter aussi des
corrections (sécurités) à mes autres fonctions:


void **malloc2d (int num, int size)

{

    void **tab, **c;


    if(num <= 0 || size <= 0) return 0;


    tab(void**)malloc(sizeof(void*)*num); c tab;

    if(!c) return 0;


    while(num > 0)

    {

        *c = (void*)malloc(size);
      
       if(*c == 0) return 0;
      

        c++; num--;

    }


    return tab;

}


void free2d (void **tab, int num)

{

    void **c = tab;


    if(c == 0 || num <= 0) return;


    while(num > 0)

    {

        free(*c);

        c++; num--;

    }


    free((void*)tab);

}


void **realloc2d (void **tab, int num, int newsize)

{

    void **d;


    if(tab == 0 || num <= 0 || newsize <= 0) return 0;


    d = tab;


    while(num > 0)

    {

        void *c = (void*)realloc(*d, newsize);


        if(!c) return 0;


        *d = c; d++; num--;

    }


    return tab;

}


Bon, voici un exemple:


char **TAB = (char**)malloc2d(2, 10);


strcpy(TAB[0], "allo ");

strcpy(TAB[1], "les amis ");


realloc2d(TAB, 2, 25); // Si la la nouvelle taille est plus petite que l'ancienne, il peut y avoir des problèmes


strcat(TAB[1], "sa va ?");


printf("%s%s\n", TAB[0], TAB[1]);


free2d(TAB, 2);

[auteurdetail.aspx?ID=17926 Galmiza] >> Tu es sûr? Il s'agit pourtant bien d'allocation dynamique.

C++ (@++)<!--
Messages postés
573
Date d'inscription
samedi 16 novembre 2002
Statut
Membre
Dernière intervention
9 avril 2008
1
Oui ;), la variable tab est créée dans la fonction, donc est détruite en sortant de la fonction.
Le système croit les 4 octets libres donc peut se permettre d'écrire dessus.

char **TAB = (char**)malloc2d(2, 10);
TAB est la copie du tab de la fonction.
Or à l'adresse de tab, n'importe quoi peut être écrit par le système.
Donc TAB (qui reste inchangé) peut pointer vers des données 'inconnues'.

Fais ainsi:
char **TAB;
TAB = (char**)malloc2d(2, 10,&TAB);
Messages postés
50
Date d'inscription
jeudi 17 novembre 2005
Statut
Membre
Dernière intervention
7 janvier 2009

Voila comment j'ai traité mon problème de réservation de mémoire pour une tableau de pointeur sur strucutre et ça marche pas mal
Une fonction que alloue de la mémoire au tableau et aux strucutres et une fonction qui libère de la mémoire la place en memoire pour
 les structures et qui diminue le nombre d'élément d'un tableau .UNEPAGE et un define qui indique le nombre d'element minimun à réserver.

/*******************************************************************************
* Fonction : augmentertaille            
* Objet : Réservation de la place mémoire


*********************************************************************************


struct tar ** augmentertaille (struct tar ** p ,int nb ) {


      /*------------------------------ DECLARATIONS ---------------------------*/


      int init;


      /*---------------------------- DEBUT DE TRAITEMENT ----------------------*/


      init = nb;


      //Pour toujours un multiple de UNEPAGE


      for (nb  ; nb < init+UNEPAGE; nb++) {


            //Augmente la taille du tableau d'un pointeur, soit 4 octets


            p = realloc (p, (nb+1) * 4);


            //Alloue la place d'une structure


            p[nb] = (struct tar *) calloc (1, sizeof (struct tar));


      }


      return p;


}


 


/********************************************


* Fonction : liberertaille *


*


* Objet : Libère la place mémoire réservée *


* *


************************************/


void liberertaille (struct tar ** p ,int nb ) {


      /*------------------------------ DECLARATIONS ---------------------------*/


      div_t divis;


      /*---------------------------- DEBUT DE TRAITEMENT ----------------------*/


      //Pour toujours un multiple de UNEPAGE


      divis = div (nb,UNEPAGE);


      for (nb = (divis.quot*UNEPAGE)+UNEPAGE - 1; nb >= 0; nb--) {


            //Libère la structue


            free (p[nb]);


            //réduit le tableau d'un pointeur,l'adresse 0 vaut un pointeur


            p = realloc (p, (nb+1) * 4);


      }


}












Timy94