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

8 réponses

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

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 ?


Exact pour le this->, en fait je ne l'utilise pas systématiquement, mais
c'était un test de plus pour trouver mon erreur :(

En fait je n'ai pas eu le choix des prototypes, et la variable newSize en
fait partie ! Je n'ai pas vraiment l'habitude de mettre des majuscules dans
mes variables sauf si j'en ai besoin pour me rappeler du type genre iNumber,
fNumber...


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

qui devrait
faire moins de 100-200 lignes


Y'a un zéro en trop : logiquement, un tel code ne doit guère dépasser
les 20 lignes.


--
;-)

Avatar
Rémy
"TigrouMeow" a écrit dans le message de
news:41604c15$0$3607$
"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.




Probablement que si.

En écrivant en dehors du tableau (ce qui n'est détecté ni en , ni en C++),
tu écrases peut-être d'autres données. Dans le cas de mémoire allouée par
new ou malloc, on écrase généralement les informations de gestion de
l'allocation de mémoire, ce qui fait planter plus tard lors d'un new/malloc
ou delete/free.

C'est un cas de bug courant en C comme en C++.

Rémy



Avatar
kanze
"TigrouMeow" wrote in message
news:<41604c15$0$3607$...
"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.


C'est une erreur classique en C.

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.


Mais si. Je l'ai vu souvent en C. (L'erreur classique, en C, c'était
d'allouer strlen() char pour copier la chaîne.)

Le résultat de l'erreur, c'est un comportement indéfini. En fait, ce qui
se passe dépend de ce qui suit ton tableau. Selon le type du tableau, et
l'algorithme qu'utilise la gestion de la mémoire, ou bien, tu tapes dans
une zone non utilisée autrement, et ça a l'air de marcher, ou bien, tu
tapes dans quelque chose utilisée par la gestion de la mémoire
dynamique, et selon le cas, tu crashes à la prochaine libération, ou à
une allocation plus tard, ou à un moment bien plus tard encore.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34



Avatar
Alexandre
bonjour,

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).
En fait je suis étudiant donc obligé de faire ça...




donc c'est un TD à faire ? Donc c'est pour que tu le fasses toi, normalement
;-)

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 !



dans ton post original tu ne montres pas où ton pointeur "tab" est alloué...
L'est-il ?
Car si le delete plante, c'est que ton "tab" n'est pas alloué, ou alors déjà
libéré, ou alors non libérable...






Avatar
Arnaud Meurgues
Alexandre wrote:

donc c'est un TD à faire ? Donc c'est pour que tu le fasses toi, normalement
;-)


Autant il est naturel de ne pas faire leurs devoir à leurs place, autant
quand des étudiants posent des questions précises sur un problème précis
montrant qu'ils y ont déjà travaillé, je ne vois pas pourquoi on ne les
aiderait pas dans la mesure du possible.

--
Arnaud
(Supprimez les geneurs pour me répondre)

Avatar
gilles.barges

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 ! :(


est-ce que par hasard tu n'aurais pas modifié le pointeur tab pendant ta copie ?

Avatar
TigrouMeow
"Gilles Barges" a écrit dans le message de
news:

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 ! :(


est-ce que par hasard tu n'aurais pas modifié le pointeur tab pendant ta
copie ?


Non en fait comme je l'ai dis précédemment j'ai parsé mon tableau
et je suis allé de 1 trop loin et j'y ai mis un truc dedans... et ça
plantait
lors du delete par la suite ;)


1 2