1

Je rencontre depuis un petit moment un problème qui a la dent dure.
Je programme sous Visual C++ 6, sous win XP.

Il s'agit de problèmes d'allocation mémoire.
Plus précisément, j'ai dans mon programme un classe X qui contient des membres étant aussi des classes un peu compliquées, et ayant une méthode d'initialisation elle aussi assez compliquée, elle ouvre plusieurs fichiers extrernes pour les lire et remplir des structures...

Depuis que j'essaie d'appeller cette méthode d'initialisation depuis une classe X allouée (pour l'allouer j'ai essayé malloc, new et même <vector> de la STL car le but est d'avoir plusieurs classes X), dans la méthode d'initialisation il y a toujours un moment ou une allocation mémoie plante (cela peut être soit sur un realloc, soit sur un push_back d'un <vector>. En général j'ai droit a une "Debug assertion", CtrlsValidHeapPointer(pUserData) ...
Quand j'appelle la méthode d'initialisation sur une instance locale de X (prise sur la pile), cela marche ! même avec tout un tableau de X !!

Peut il s'agir d'un problème concernant la taille du Heap ?? Je n'y connait pas grand chose.
Mon programme consomme pas mal de mémoire, de l'ordre de 20 Mo mais le problème semble insensible à la quantité de RAM déja allouée pour ce problème... Donc j'imagine qu'il s'agit plutôt d'un problème de Heap.

Merci pour toute aide
Mon site :
[TI68k] Space Dementia I : Version 0.8
[TI68k] Space Dementia II, mod arena : Version 0.3 avec IA
[OpenGL] Environment Mapping 3ds Viewer : version 1.0
[OpenGL] Programmation d'une simulation de voiture avec le moteur physique Tokamak

2

Les erreurs d'assertion sur _CrtIsValidHeapPointer, c'est généralement quand on agit sur un pointeur déjà libéré...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

3

Link :
Les erreurs d'assertion sur _CrtIsValidHeapPointer, c'est généralement quand on agit sur un pointeur déjà libéré...


Oui, je sais, mais là ce qui est bizarre c'est qu'il me balance cette assertion sur un push_back() de "vector", a priori mes pointeurs n'ont rien a voir avec ca...

Acutellement, plus précisément, il plante au troisième push_back(), au troisième élément ajouté dans la liste donc.
Mon site :
[TI68k] Space Dementia I : Version 0.8
[TI68k] Space Dementia II, mod arena : Version 0.3 avec IA
[OpenGL] Environment Mapping 3ds Viewer : version 1.0
[OpenGL] Programmation d'une simulation de voiture avec le moteur physique Tokamak

4

un push_bakc sur un vecteur c'est simplement l'écriture dans un tableau
si tu as de la corruption avant, c possible que ca te fasse cela... regarde l'état de ta zone mémoire

5

Tu peux nous montrer ta routine d'allocation ? Tu peux simplifier ton programme jusqu'à avoir une version simple où le bug apparaît ?

6

ex-Miles :
Tu peux nous montrer ta routine d'allocation ? Tu peux simplifier ton programme jusqu'à avoir une version simple où le bug apparaît ?


Mon programme est trop énorme et trop de classes sont imbriquées dans ce problème.

En fait, j'ai trouvé la source de l'erreur : une classe dont le constructeur n'était pas appellé, qui avait un pointeur non mis à null, et donc en faisant un realloc dessus ca plantait car le pointeur ne pointait sur rien. et le constructeur n'était pas appellé car la classe fait partie d'un tableau alloué, avec realloc (et pas new).

merci pour vos réponses !

Donc maintenant je n'utilise plus de vecteurs mais que des tableau agrandis à chaque fois avec realloc, et fais gaffe au fait que les constructeurs ne sont pas appellés.

Sinon un autre question sur ce sujet, existe t-il un équivalent à realloc qui appelle les constructeurs : pour l'allocation le C++ fournit new et delete, mais pas d'équivalent de realloc. Faut il passer forcément par les vecteurs dans ce cas ?
Mon site :
[TI68k] Space Dementia I : Version 0.8
[TI68k] Space Dementia II, mod arena : Version 0.3 avec IA
[OpenGL] Environment Mapping 3ds Viewer : version 1.0
[OpenGL] Programmation d'une simulation de voiture avec le moteur physique Tokamak

7

Tu peux appeler explicitement les constructeurs, j'ai lu ça récemment sur MSDN.

Un truc du genre:
CMaClasse *pt_maClasse = realloc(.....);
pt_maClasse->CMaClasse();
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

8

Les vecteurs sont encore le mieux, ou les listes aussi.

9

merci !
Mon site :
[TI68k] Space Dementia I : Version 0.8
[TI68k] Space Dementia II, mod arena : Version 0.3 avec IA
[OpenGL] Environment Mapping 3ds Viewer : version 1.0
[OpenGL] Programmation d'une simulation de voiture avec le moteur physique Tokamak

10

moitib
: Sinon un autre question sur ce sujet, existe t-il un équivalent à realloc qui appelle les constructeurs : pour l'allocation le C++ fournit new et delete, mais pas d'équivalent de realloc. Faut il passer forcément par les vecteurs dans ce cas ?

Tu peux toujours utiliser un resize du vector.

11

Sinon un autre question sur ce sujet, existe t-il un équivalent à realloc qui appelle les constructeurs : pour l'allocation le C++ fournit new et delete, mais pas d'équivalent de realloc. Faut il passer forcément par les vecteurs dans ce cas ?
Utiliser du malloc dans un programme en C++ est une *très* mauvaise pratique, qui en plus est très casse-gueule. Selon l'implémentation, malloc peut renvoyer vers new, l'inverse, ou alors chaque jeu de fonctions peut maintenir un pool mémoire distinct.
=> vire ça tout de suite grin

En passant, les fonctions des stl utilisent des allocators pour récupérer leur mémoire. Il est possible de passer des allocators custom pour certains besoins spécifiques (l'allocator par défaut utilise new). Ce n'est donc pas un problème d'utiliser new et les stl en même temps. Au contraire, c'est fait pour.
CMaClasse *pt_maClasse = realloc(.....); pt_maClasse->CMaClasse();

Et pan, direct dans le mur.
1) le destructeur ne sera pas appelé à la libération, free() est une fonction C pas C++.
2) voir ci-dessus pour l'utilisation de *alloc dans un programme c++
3) cet appel n'est pas propagé aux classes héritées.
4) les initialisations de la classe propres au compilateur ne sont pas effectuées (notamment les tables de fonctions virtuelles)

Félicitations, tu viens je pense de faire un top50 dans mon tableau des trucs les plus horribles qu'il m'ait été donné de voir. tongue



En note final, voici un truc aussi moche que ta proposition, mais en version qui marche (j'ai pas compilé, mais ça devrait être ça) :
void * CMaClasse:: operator new(size_t, void * p)  {return p;}

// Puis là où tu fais ton truc moche
void * memory = alloc(........);
CMaClasse * pt_maClasse = new(memory) CMaClasse(...);

Mais c'est quand même ignoble hein, utilise les STL c'est fait pour, les algorithmes sont plus efficaces que tout ce que tu pourras refaire toi même, et c'est bien débuggé.

12

(t1 j'apprends des trucs mwa grin pas de malloc pour initialiser une classe, je pensais pas que ça pouvait marcher d'ailleurs grin)

une classe n'est donc rien de mieux qu'un struct un peu mieux géré?

13

oui tout a fait
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

14

en C++, struct et class sont la même chose, à une différence près :
- struct : tout public par défaut
- class : tout privé par défaut

(enfin, j'ai pas testé (et jamais vu faire), mais je pense qu'on peut faire avec struct tout ce qu'on peut faire avec class - genre héritage et tout... enfin, je serai curieux de savoir si c'est possibnle ou non, en fait ^^)
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

15

oui, c possible...

16

squale> pas seulement, en C++ tu as deux types de struct : celles dont tu parles, à savoir les "classes déguisées", et les Plain Old Data, à savoir les bonnes vieilles struct du C (qui ne peuvent pas avoir de constructeurs/destructeurs ni de fonctions membres)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

17

Pollux: j'imagine que le compilo détecte si c'est un plein old si aucune methode ou de "public/private a co" se trouve dedans, sinon c'est une classe
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

18

c'est pas ce que j'ai dit trifus

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

19

nan ta pas dit de choses la dessus
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

20

bah j'ai donné la définition des POD, après c'est vrai que j'ai pas dit que le compilo applique effectivement cette définition pour savoir si c'est un POD ou non trioui

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

21

ce qui m'amuse maintenant, c'est de voir tout ce que le kernel linux programme en object-like sans un .cpp dedans smile
le coup des pointeurs de fonctions avec des structures, c'est ce qui m'a motivé à regarder le cpp en me demandant si c'était pas la même chose trifus

22

Ben, c'est un peu le principe de COM... Regarde dans ObjBase.h l'aide de la macro DECLARE_INTERFACE: Un hack qui d'utiliser en C un pointeur vers une classe C++...
avatar
Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.

23

oué, j'imagine. j'ai déja vu l'interface de la JNI.