OVH Cloud OVH Cloud

[Débutant] Problème de libération d'un pointeur

18 réponses
Avatar
TigrouMeow
Hello ;)

J'ai une classe où j'ai un pointeur int *tab en private. Je veux alloué
dynamiquement plusieurs fois, car c'est un tableau qui va évoluer dans le
temps...

Au moment d'une évolution, ma logique en C aurait été de faire un malloc de
la nouvelle taille, de faire une copie si besoin, de faire un free sur la
valeur actuelle du pointeur, et de copier le pointeur nouvellement créé sur
le "tab".

En C+ c'est ce que je fais (d'après tous les cours que j'ai pu voir le
principe est le même...) :
int *newtab = new int[newSize];
/* je rempli mon tableau... */
if (tab) // tab est
delete tab;
tab = newtab;

Malheureusement, j'ai toujours un plantage sur le delete tab... merci de
votre aide, j'ai beau cherché, je comprend rien ! :(


--
TigrouMeow

10 réponses

1 2
Avatar
Fabien LE LEZ
On Sun, 3 Oct 2004 19:56:30 +0200, "TigrouMeow"
:

En C+ c'est ce que je fais


Erreur. En C++ on utilise soit un tableau (std::vector<>) soit un
pointeur intelligent.

Note en passant que faire un delete sur un pointeur alloué par new[]
ne fonctionne pas.
new[] => delete[]
new => delete


--
;-)

Avatar
TigrouMeow
"Fabien LE LEZ" a écrit dans le message de news:

On Sun, 3 Oct 2004 19:56:30 +0200, "TigrouMeow"
:

En C+ c'est ce que je fais


Erreur. En C++ on utilise soit un tableau (std::vector<>) soit un
pointeur intelligent.

Note en passant que faire un delete sur un pointeur alloué par new[]
ne fonctionne pas.
new[] => delete[]
new => delete


Oui mais en gros je suis obligé de recoder la classe vector (sans les
templates, en considérant que c'est un vecteur d'int et c'est tout).

J'ai essayé delete[] tab ça ne fonctionne pas non plus...

En gros voici la partie de code qui ne fonctionne pas, et qui est censée
faire comme un realloc (sauf que je n'ai pas mis le code qui recopie ici) :

int *newtab = new int[newSize];
//if (tab)
// delete[] this->tab;
tab = newtab;

Ca plante sur le delete bien sur... en le décommentant tout fonctionne...
mais j'imagine pas les fuites mémoires !


Avatar
Loïc Joly
TigrouMeow wrote:
Oui mais en gros je suis obligé de recoder la classe vector (sans les
templates, en considérant que c'est un vecteur d'int et c'est tout).


Quelles sont les circonstances qui t'obligent à ça ?


J'ai essayé delete[] tab ça ne fonctionne pas non plus...


Souvent, dans ce genre de cas, la vérité est ailleurs, et ta memoire est
déjà corrompue, mais tu ne le sais que lorsque tu tentes de la libérer.

Bonne chance pour la recherche de ce genre de bug.

--
Loïc

Avatar
Vincent Lascaux
Oui mais en gros je suis obligé de recoder la classe vector (sans les
templates, en considérant que c'est un vecteur d'int et c'est tout).


Gni ? pourquoi tu veux recoder la classe vector ?
Tu peux faire std::vector<int> tab(newSize); et ensuite tu utilises tab
comme un tableau.
La libération de la mémoire utilisée par le vecteur est faite à la
destruction de ton objet.

--
Vincent

Avatar
TigrouMeow
"Loïc Joly" a écrit dans le message de news:
41604471$0$17189$
TigrouMeow wrote:
Oui mais en gros je suis obligé de recoder la classe vector (sans les
templates, en considérant que c'est un vecteur d'int et c'est tout).


Quelles sont les circonstances qui t'obligent à ça ?


J'ai essayé delete[] tab ça ne fonctionne pas non plus...


Souvent, dans ce genre de cas, la vérité est ailleurs, et ta memoire est
déjà corrompue, mais tu ne le sais que lorsque tu tentes de la libérer.

Bonne chance pour la recherche de ce genre de bug.


En fait je suis étudiant donc obligé de faire ça... cela dit ce que j'ai à
faire n'est pas si compliqué que ça normalement... bon j'ai bien vérifié la
valeur de mon pointeur une fois allouée, quand je fais un delete dessus
l'adresse n'a pas changée... vu que c'est un membre private de la classe je
l'ai passé en public pour voir si c'était ça qui empéchait le delete (on
sait jamais) mais c'est pas ça non plus... je sais plus du tout où chercher,
mon code est très simple et très court (mais pas très "postable"), donc si
quelqu'un veut bien que je lui envoi, ça serait avec grand plaisir, je suis
depuis 2h dessus et j'ai fouillé partout sur le net dans des tutoriels et
impossible de trouver la solution ! Merci beaucoup !


Avatar
Vincent Lascaux
bon j'ai bien vérifié la valeur de mon pointeur une fois allouée, quand je
fais un delete dessus l'adresse n'a pas changée... vu que c'est un membre
private de la classe je l'ai passé en public pour voir si c'était ça qui
empéchait le delete (on sait jamais) mais c'est pas ça non plus... je sais
plus du tout où chercher, mon code est très simple et très court (mais pas
très "postable"), donc si quelqu'un veut bien que je lui envoi, ça serait
avec grand plaisir, je suis depuis 2h dessus et j'ai fouillé partout sur
le net dans des tutoriels et impossible de trouver la solution ! Merci
beaucoup !


Tu fais bien un delete[], et pas un delete, hein ?
Pour trouver le bug, une méthode qui a fait ses preuves est de supprimer le
plus de code possible tout en conservant le bug. Essaie de retirer petit à
petit à petit tout ce qui ne concerne pas le tableau dans ton programme,
puis le traitement sur le vecteur... et si quand tu arrives au point ou tu
ne peux plus rien retirer sans perdre le bug, et que tu ne comprends
toujours pas pourquoi ca ne marche pas, tu postes ton code (qui devrait
faire moins de 100-200 lignes) ici.

--
Vincent

Avatar
Fabien LE LEZ
On Sun, 3 Oct 2004 19:31:30 +0100, "Vincent Lascaux"
:

Gni ? pourquoi tu veux recoder la classe vector ?


Exercice scolaire, a priori.


--
;-)

Avatar
Fabien LE LEZ
On Sun, 3 Oct 2004 19:56:30 +0200, "TigrouMeow"
:

if (tab) // tab est


Cette ligne ne sert à rien -- delete sur un pointeur nul est valide
(et est une no-op).

delete tab;



--
;-)

Avatar
Fabien LE LEZ
On Sun, 3 Oct 2004 20:20:47 +0200, "TigrouMeow"
:

//if (tab)
// delete[] this->tab;


Ah oui mais non.
Certains écrivent systématiquement "this->" devant tous les noms de
variables membres. Je trouve que c'est une mauvaise idée, sauf dans
les cas où c'est réellement utile, mais si on décide de le faire, il
faut le faire partout.
Donc, si tu écris "if (tab)" sans le "this->", le mettre dans la ligne
suivante pour désigner la même variable, est une erreur (au moins de
style).

Le code corrigé est :

int *newtab= new int[newSize];
delete[] tab;
tab= newtab;

Au fait, autre problème de style : pourquoi y a-t-il une majuscule au
milieu de newSize (convention Java je suppose ?) et pas de t majuscule
à newtab ?


--
;-)

Avatar
TigrouMeow
"Fabien LE LEZ" a écrit dans le message de news:

On Sun, 3 Oct 2004 19:56:30 +0200, "TigrouMeow"
:

if (tab) // tab est


Cette ligne ne sert à rien -- delete sur un pointeur nul est valide
(et est une no-op).

delete tab;



Ah merci je savais pas !

Et je viens de trouver mon erreur... en fait, sur cette tab, je faisais une
opération sur sa dernière "case"... mais en fait pour moi la dernière case
était de 1 trop loin, du coup en dehors de la zone mémoire allouée. Ce qui
est étrange, c'est que le plantage ne se faisait pas là, mais beaucoup
beaucoup plus loin lors du delete. En C une erreur de ce genre n'aurait pas
eu du tout le même comportement.


1 2