CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C++/win32] gestion du tas

dnob700
dnob700
Niveau 10
03 septembre 2006 à 00:04:21

pour une raison qui m´est pour l´instant propre, je cherche à faire quelquechose d´assez spécial :

j´ai un programme qui appel des fonctions dans des DLL. Mais j´aimerais que si jamais les DLL allouent de la mémoire (avec malloc ou new) lorsque j´appel une de leurs fonctions, elles soient forcées de la désallouer avant de rendre la main.

la méthode que j´ai trouvé est de controler la taille du tas utilisé par le programme.

Ca ne vas pas sans mal car il n´existe pas de fonction pour ça, mais on peut parcourir chaque élément du tas et récupérer sa taille. En sommant le tout, on a l´info voulue.

Mais là, les choses se corses :

car j´ai fait quelques tests et à ma grande surprise, la mémoire allouée sur le tas est inférieur après que j´ai fait appel à new ! (et sur un gros tableau).

alors je ne comprend pas trop ce qui se passe.

Ma seul idée est qu´il existe une unité de mémoire sous le tas et que new alloue dans le tas de gros bloc de mémoire (en profitant des fonctionnalité offerte par windows pour gérer ces blocs) puis gère lui même l´intérieur de ces blocs de manière plus fine.

(mais en regardant le code dans le crt, ça n´a pas l´air d´être le cas).

bref, est ce que vous pouvez tester ce phénomène sur vos machines ? et me dire ce que vous obtenez ?

le code est là :
http://wall.sectionpc.info/C/tas.cpp

kufa
kufa
Niveau 9
05 septembre 2006 à 20:24:45

pour une raison qui m´est pour l´instant propre, je cherche à faire quelquechose d´assez spécial :

Oui effectivement c´est tres special ce que tu cherches a faire.
Imaginons que tu parvienne a tes fins, rien ne te garantie que la dll soit dans un etat stable. Par exemple si au premier appel d une fonction, une initialisation est effectuee (style instanciation d un singleton) et que sa memoire est libere, pas top..

Bon en revenir a tes questions: sauf erreur de ma part, c´est bel est bien WinHeap qui est utilise par le crt de windows. L´implementation de celui-ci est bien entendu bien plus complique qu´il n´y parait, il y a la gestion de la memoire virtuelle et des pages memoire en dessous. Le "phenomene" que tu observes est clairement normal.
Si tu veux avoir un acces plus "fin" aux blocs de memoire alloues, il faut utiliser les fonctions de debug memoire du crt, ou reimplementer ton new et malloc (ce qui se fait assez facilement). Mais comme une dll utilise sa propre heap et que tu ne link pas avec comme pour une lib, ca ne t´aideras pas vraiment bcp ici.

Si tu peux preciser un peu plus pourquoi tu veux faire cela (meme si je te le deconseille mais alors tres vivement sauf cas tres particuliers), on peut probablement trouver des solutions alternatives.

/k

dnob700
dnob700
Niveau 10
05 septembre 2006 à 22:46:34

merci pour tes conseils. Pour répondre à tes question :

en fait, je suis en train d´écrire une espèce de jeu à la manière de ce qui se fait pour le prologin où différentes IA (chacune exportée par une DLL) s´affrontent. Mais, dans mon cas, ces IA sont supposées diriger des fourmis, mais pas comme un être qui dirigerait une fourmilière, mais plutôt comme une IA qui dirigerait chaque fourmis indépendamment. Et donc lorsque la fonction chargé de faire jouer une fourmis est appelé avec les information d´une fourmis, je veux qu´elle ignore tout des autres fourmis (qui ne sont pas dans son champ visuelle, ou dans ce qu´elle a pu voir auparavant).

Bien sûr, je peut faire confiance au programmeur pour ça (c´est comme ça que ça fonctionne pour l´instant), mais je cherchais un moyen pour que mon programme force les DLL à respecter ça (et puis c´est une question théorique interessante, au delà du cadre de ce que je suis en train d´écrire) (car chaque DLL est appelé une fois pour chaque fourmis qu´elle contrôle (typiquement, toutes celles d´une fourmilière) et ne doivent rien stocker entre les appels).

Alors je me suis dit que contrôler le tas pouvait être un bon moyen, car pour stocker les info une DLL doit forcément demander de la mémoire (sauf à avoir allouer en statique une grosse quantité de mémoire qui doit lui suffire pour tout (mais ça, on peut le contrôler au chargement), ou a écrire dans des fichiers (là j´ai pas trop d´idée pour l´empêcher)).

Et si jamais une DLL triche, alors je la décharge juste, ce n´est pas critique pour mon programme.

Bref, j´ai un peu avancé car l´idée de mon code ci-dessus est juste ; seulement tout les bloc dans le tas ne sont pas utilisés, et parfois un appel à new réorganise le tas et va supprimer des blocs (dont je ne connais pas l´utilité, mais il doit y en avoir car ils sont restauré plus tard).

Par contre, en contrôlant que les blocs ont le drapeaux PROCESS_HEAP_ENTRY_BUSY et en n´ajoutant leur taille au total que si c´est le cas, j´obtiens exactement ce que je veux (un total de la mémoire alloué avec new et malloc, même si cela est fait par une DLL (et à la limite, même si elle poussait le vice jusqu´à se créer son propre tas).

bon bien sûr, rien n´empêche un programmeur de s´allouer quelques pages dans la mémoire virtuelle du processus et de la gérer lui même sans passer par les fonction de gestion du tas de windows, mais là, ça deviendrait sadique de sa part, et puis ça peut se contrôler aussi.

godrik
godrik
Niveau 30
05 septembre 2006 à 22:59:48

et comment veux tu empecher la DLL d´aller taper dans la mémoire de ton application ?
(Personnellement pour regler ce genre de probleme, je ferais plusieurs processus.)

dnob700
dnob700
Niveau 10
06 septembre 2006 à 01:22:45

l´empêcher : je ne peux pas. Mais si elle le fait, je la tue (c´est-à-dire que cette IA là a automatiquement perdue, et on peut afficher un message comme quoi son concepteur a triché car il n´a pas respecté la règle).

godrik
godrik
Niveau 30
06 septembre 2006 à 11:15:14

Mais il faut pouvoir le detecter. C´est faisable ?

Sous forums
  • Aide à l'achat Mac
  • Internet
  • Macintosh
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Steam Deck
  • Hardware
La vidéo du moment