(Débutant) Malloc et gestion de mémoire

a marqué ce sujet comme résolu.

Bonjour, d’abords désolé si je pollue le forum, j’ai cherché avant de poster mais je n’ai rien trouvé

Voilà, je me retrouve avec cette fonction en sachant que:

-coup est une structure quelconque

-plateauJeu est une structure contenant: un tableau de coup un entier "max" représentant la taille du tableau un entier "prochaineCase" qui donne quelle est la prochaine case du tableau quand laquelle il faut écrire

Cette fonction a pour but de doubler la taille du tableau si jamais il est plein

Étant encore étudiant je voulais être sur que la libération de mémoire était bien effectué pour ne pas prendre de mauvaise habitude

void augmenteTaille (plateauJeu* p)
{
    if (p->prochaineCase==1+p->max)
    {
        plateauJeu* plo;
        plo->tab= (coup*) malloc(2*p->max*sizeof(coup));
        for (int i=0;i<p->max;i++)
        {
            plo->tab[i]=p->tab[i];
        }
        free(p->tab);
        p->tab=plo->tab;
        p->max+=p->max;
    }
}

Je suspecte aussi qu’il y ai une erreur ou deux, je pense pas encore avoir saisis les pointeurs et mon compilateur me renvoie :

Pointeur.c:62:11: attention: « plo » pourrait être utilisé sans être initialisé dans cette fonction

[-Wmaybe-uninitialized]

62 | plo->tab= (coup) malloc(2p->max*sizeof(coup));

Merci beaucoup !

Salut,

Oui la libération est bien faite. Cependant, plo pointe sur n’importe quoi, donc essayer de modifier le pointeur plo->tab, mauvaise idée. Mais tu n’as pas besoin de plo, ce qui t’intéresse, c’est juste d’allouer un nouveau tableau de coups.

coup *tab = malloc(2*p->max*sizeof(coup));
/* Le reste avec tab au lieu de plo->tab. */

On va rajouter quelques trucs.

  1. Vérifie ton allocation (le retour de malloc).
  2. Pas la peine de caster le retour de malloc.
  3. Pourquoi ne pas utiliser realloc ?
  4. Implémente une structure opaque pour gérer ton tableau redimensionnable. Tu aurais des fonctions pour ajouter un élément, accéder à un élément, etc. Et les allocations seraient faites de manière opaque dans des fonctions de ta structure que tu n’auras plus à gérer.
+1 -0

Salut,

Oui la libération est bien faite. Cependant, plo pointe sur n’importe quoi, donc essayer de modifier le pointeur plo->tab, mauvaise idée. Mais tu n’as pas besoin de plo, ce qui t’intéresse, c’est juste d’allouer un nouveau tableau de coups.

coup *tab = malloc(2*p->max*sizeof(coup));
/* Le reste avec tab au lieu de plo->tab. */

On va rajouter quelques trucs.

  1. Vérifie ton allocation (le retour de malloc).
  2. Pas la peine de caster le retour de malloc.
  3. Pourquoi ne pas utiliser realloc ?
  4. Implémente une structure opaque pour gérer ton tableau redimensionnable. Tu aurais des fonctions pour ajouter un élément, accéder à un élément, etc. Et les allocations seraient faites de manière opaque dans des fonctions de ta structure que tu n’auras plus à gérer.
Karnaj

Merci pour cette réponse !

Pour les points précisé:

1- Comment je fais ça ?

2- Mon prof m’a expliqué que c’était a faire + ou - tout le temps vu que Malloc renvoie un pointeur qui pointe n’importe ou (Ce n’est pas ses mots, c’est ce dont je me souviens, je suis pas sur que ce soit bien la même chose)

3- Parce que ca n’est pas dans mon cours, je ne la connais absolument pas a vrai dire !

4- Alors je ne sais pas du tout ce que signifie une structure opaque*, ce n’est pas dans mon cours non plus, et vu que je ne sais pas qui me corrigera je préfère pas improviser

Ah oui merci, j’avais pensé que p->max aurait été augmenté avant.

entwanne

J’aurais aussi fait comme ça intuitivement mais il est demandé d’augmenter le max en dernier

+0 -0

Non il faut le faire en dernier parce que si ta réallocation échoue, il n’y a pas besoin de faire revenir tes champs à l’état précédent : la structure est déjà dans le bon état.

Pour tester le retour de malloc rien de plus simple, il est nul en cas d’échec (et donc s’il est nul, il ne faut pas mettre à jour la structure juste renvoyer un code d’erreur).

En C il n’y a aucune raison de cast le retour de malloc puisque cette opération n’a strictement aucun effet et que le typeur s’en fout de mettre du void* dans whatever*: c’est autorisé.

Les professeurs conseillent souvent de caster le retour de malloc car ils ont en tête qu’ils vont t’apprendre le C++ derrière. Et en C++, c’est important de caster le retour de malloc car le cast n’est pas automatique.

Bref, c’est un peu le problème d’enseigner le C puis le C++. Cast si tu es en C++, ne cast pas si tu es en C.

+0 -0

Bonjour,

Je suis un peu supris par la réponse de Ache:

Bref, c’est un peu le problème d’enseigner le C puis le C++. Cast si tu es en C++, ne cast pas si tu es en C.

ache

Pour moi: Ne cast pas si tu es en C, n’utilise pas malloc si tu es en C++. Soit tu utilises new(), (si tu n’as pas peur des fuites mémoire), soit le RAII, la STL, Pointeur intelligent, …

Je me trompe ?

Cordialement.

Effectivement !

En C++, on ne devrait jamais utiliser malloc et les cas où on rencontre un void* devraient resté très rare.

Ce que je voulais dire, c’est que ce sont des profs de C++ qui enseignent le C, d’où le problème.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte