Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Heu, problème de pointeur où... (âge, fatigue...)

30 réponses
Avatar
Arnold McDonald \(AMcD\)
Voici une heure que je sèche sur ce truc...

J'ai une table de chaînes :

PTCHAR tab[] = { TEXT("yo"),TEXT("yi!") };

Bien, je veux modifier les chaînes de cette table. Donc...

PTCHAR p = new TCHAR[20];
PTCHAR q = new TCHAR[25];

lstrcpy(p,TEXT("héhé"));
lstrcpy(q,TEXT("hum!"));

Bon, ici, mes chaînes sont créées. Changeons celles de tab[].

tab[0] = p;
tab[1] = q;

Bien, bien bien. Le soft tourne, OK (comment pourrait-il en être autrement
vu la "difficulté"...).

Mais voici, en fin d'application, je dois désallouer les chaînes créées
(soyons propre). Je fais donc :

delete [] tab[0];
delete [] tab[1];

ben non, ça plante... Un beau "heap corruption detected".

Un delete tab[0] ne vaudrait guère mieux :-). Est-ce la fatigue qui fait que
je ne vois pas où j'oublie quelque chose ?

10 réponses

1 2 3
Avatar
Remi THOMAS
"Arnold McDonald (AMcD)"
Voici une heure que je sèche sur ce truc...

J'ai une table de chaînes :

PTCHAR tab[] = { TEXT("yo"),TEXT("yi!") };

Bien, je veux modifier les chaînes de cette table. Donc...

PTCHAR p = new TCHAR[20];
PTCHAR q = new TCHAR[25];

lstrcpy(p,TEXT("héhé"));
lstrcpy(q,TEXT("hum!"));

Bon, ici, mes chaînes sont créées. Changeons celles de tab[].

tab[0] = p;
tab[1] = q;

Bien, bien bien. Le soft tourne, OK (comment pourrait-il en être autrement
vu la "difficulté"...).

Mais voici, en fin d'application, je dois désallouer les chaînes créées
(soyons propre). Je fais donc :

delete [] tab[0];
delete [] tab[1];

ben non, ça plante... Un beau "heap corruption detected".

Un delete tab[0] ne vaudrait guère mieux :-). Est-ce la fatigue qui fait
que je ne vois pas où j'oublie quelque chose ?




Bonjour,

Je viens de faire une maquette pour être certain et rien d'anormal si tu as
bien
typedef TCHAR * PTCHAR;
La corruption doit venir d'autre part.

Rémi
Avatar
Cyrille Szymanski
"Arnold McDonald (AMcD)" wrote in
news:463f6565$0$31990$:

Mais voici, en fin d'application, je dois désallouer les chaînes
créées (soyons propre). Je fais donc :

delete [] tab[0];
delete [] tab[1];

ben non, ça plante... Un beau "heap corruption detected".



Le code a l'air correct.

As-tu réussi à reproduire le cas sur un exemple minimaliste ?

Ce qui se passe probablement c'est qu'à un moment donné dans ton programme
tu écris en dehors d'une zone allouée (probablement sans rapport avec la
variable tab), cela corrompt la mémoire du coup delete ne fonctionne plus
correctement car il ne retrouve plus ses petits.

Tu as essayé avec un soft style Rational Purify ?

--
Cyrille Szymanski
Avatar
Arnold McDonald \(AMcD\)
Je viens de trouver. Vraiment le truc à la noix...

En fait, dans mon code réel, je ne fais pas :

PTCHAR p = new TCHAR[20];

mais un new en fonction de la longeur de la chaîne de caractères que je vais
y copier. Donc, par exemple :

PTCHAR p = new TCHAR[lstrlen(TEXT("yo!")];

Vous voyez le gag ? Non ? C'est con comme tout...

L'instruction ci-dessus alloue la place pour les trois caractères "yo!",
mais pas pour le 0 terminal. Il faut donc rajouter + 1 pour le '' ! Bref,
le genre de bug sur lequel on peut passer 3 heures, puisque le bug
n'apparaîtra que lorsque le compilo génèrera une erreur lors de la
désallocation de la mémoire sur le heap :-(.

Merci à vous deux.

--
Arnold McDonald (AMcD)

http://arnold.mcdonald.free.fr/
Avatar
Bertrand Lenoir-Welter
Arnold :

mais un new en fonction de la longeur de la chaîne de caractères que je vais
y copier. Donc, par exemple :
PTCHAR p = new TCHAR[lstrlen(TEXT("yo!")];



'fectivement, tu vieillis !
Avatar
Arnold McDonald \(AMcD\)
Bertrand Lenoir-Welter wrote:
Arnold :

mais un new en fonction de la longeur de la chaîne de caractères que
je vais y copier. Donc, par exemple :
PTCHAR p = new TCHAR[lstrlen(TEXT("yo!")];



'fectivement, tu vieillis !



Mais heu !

En fait, l'instruction exacte est bien plus complexe, c'est pour ça... :p

--
Arnold McDonald (AMcD)

http://arnold.mcdonald.free.fr/
Avatar
Sylvain
Arnold McDonald (AMcD) wrote on 08/05/2007 23:25:

En fait, l'instruction exacte est bien plus complexe, c'est pour ça... :p



m'ouais, m'ouais ...
btw, t'es sur que toute cette complexité ne masque pas un tableau de
chaînes statiques qu'il est peut être inutile de recopier ?

Sylvain.
Avatar
Arnold McDonald \(AMcD\)
Sylvain wrote:

m'ouais, m'ouais ...
btw, t'es sur que toute cette complexité ne masque pas un tableau de
chaînes statiques qu'il est peut être inutile de recopier ?



Vi, elles sont statiques. Et chiffrées... Il faut bien les déchiffrer.

--
Arnold McDonald (AMcD)

http://arnold.mcdonald.free.fr/
Avatar
Sylvain
Arnold McDonald (AMcD) wrote on 09/05/2007 01:30:

m'ouais, m'ouais ...
btw, t'es sur que toute cette complexité ne masque pas un tableau de
chaînes statiques qu'il est peut être inutile de recopier ?



Vi, elles sont statiques. Et chiffrées... Il faut bien les déchiffrer.



sûrement oui, mais elles ont besoin d'être dupliquées pour être
déchiffrées ? (déchiffrer in-place n'est que rarement le meilleur choix).

Sylvain.
Avatar
Arnold McDonald \(AMcD\)
Sylvain wrote:

Vi, elles sont statiques. Et chiffrées... Il faut bien les
déchiffrer.





sûrement oui, mais elles ont besoin d'être dupliquées pour être
déchiffrées ? (déchiffrer in-place n'est que rarement le meilleur
choix).



Heu, comment tu modifies des chaînes *statiques* ? Une chaîne constante, si
tu la modifies, boum, access violation writing exception. Normal d'ailleurs,
sinon ce serait plus une chaîne constante...

--
Arnold McDonald (AMcD)

http://arnold.mcdonald.free.fr/
Avatar
Sylvain
Arnold McDonald (AMcD) wrote on 10/05/2007 01:17:

Heu, comment tu modifies des chaînes *statiques* ? Une chaîne constante, si
tu la modifies, boum, access violation writing exception. Normal d'ailleurs,
sinon ce serait plus une chaîne constante...



je disais justement que je ne veux pas modifier les strings constantes,
statiques, éventuellement (*) chiffrées.

le déchiffrement sera donc fait par une fonction:

ret decrypt(const char* inStr, size_t inLen, char*[*] outStr);

la raison principale à ce traitement non in-place est de pouvoir
utiliser des block-ciphers tel CBC.

dès lors les chaines chiffrées n'ont pas besoin d'être recopiées dans un
élément de 'tab', au contraire ce tableau sera initialisé avec des null
et le résultat du déchiffrement y sera stocké après allocation.

(*) je dis éventuellement car j'ai quand même un doute que tu utilises
strlen() sur des chaines chiffrées ...

Sylvain.
1 2 3