Tuto sur l'allocation de memoire, les Poke et les Peek

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Patrick88
Messages : 1564
Inscription : mer. 21/janv./2004 18:24

Message par Patrick88 »

bin si, t'as touché à la mémoire, les variables entiers, string, flottant ...
les procedures, les structures.... le code.. tout ça , ça trifouille la mémoire
seulement , c'est transparent pour l'utilisateur...

alors qu'avec les pointeurs, c'est l'utilisateur qui gère la position en mémoire
l'allocation, le fonctionnement des variables ...

en gros, corrigé moi si je me trompe, mais c'est comme ça que je le vois.

ça permet de faire plus de trucs beaucoup plus pointu que le standard du langage, mais quand ça plante, c'est plus méchant...

patrick
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Admettons que tu aies une structure comme celle ci

Code : Tout sélectionner

Structure Personnage
   MapX.w
   MapY.w
   EcranX.w
   EcranY.w
   DX.b
   DY.b
   AtteindreX.w
   AtteindreY.w
   AutoriseChgtDirection.b
   NoSprite.w
   Image.w
   Sens.b
   Mini.w
   Maxi.w
   Temps.l
   TempsMaxi.w
   Vitesse.w
EndStructure
elle va te permettre de gérer plusieurs sprites dans un jeu .
Par exemple
Ordi.Personnage
Joueur.Personnage

Pour gérer l'animation de tes sprites tu peux utiliser les pointeurs de la façon suivante :

Code : Tout sélectionner

Procedure AnimationSprite(*Perso.Personnage)

   If GetTickCount_() - *Perso\Temps > *Perso\TempsMaxi
      *Perso\Image + 1
      *Perso\Temps = GetTickCount_()
   EndIf

   If *Perso\Image > *Perso\Maxi : *Perso\Image = *Perso\Mini : EndIf

   ClipSprite(*Perso\NoSprite,24 * *Perso\Image,32 * *Perso\Sens,24,32)

   DisplayTransparentSprite(*Perso\NoSprite,*Perso\EcranX + 5,*Perso\EcranY)

EndProcedure
et tu appelles la procedure ainsi

Code : Tout sélectionner

AnimationSprite(@Ordi)
AnimationSprite(@Joueur)
Je pourrais ainsi gérer des dizaines de sprites avec la même structure , et une seule procédure .

Extrait de la doc
Pour trouver l'adresse d'une variable dans votre code, utilisez le symbole @. La raison la plus fréquente d'utiliser ce système est le transfert d'une variable de type structure à une procédure. Il faut passer un pointeur à la procédure car il est impossible de passer directement la structure comme argument.
Pierre
Messages : 244
Inscription : ven. 23/janv./2004 20:29
Localisation : 77 (Région parisienne)

Message par Pierre »

MERCI!
j'ai regardé ton code et je vois que les pointeurs c'est comme les tableaux!!!!
alors vaux mieux utiliser les pointeurs ou les tableaux?



sinon j'ai regardé les codes de ce sujet et j'ai compris, maintenant j'ai plus qu'a fait quelques trucs avec ça et ça sera bien aquis :) !!!
impossible de passer directement la structure comme argument .
c'est quoi passer la procedure comme argument?
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Pierre a écrit :alors vaux mieux utiliser les pointeurs ou les tableaux?
Dans un bouquin sur le C , j'ai lu que
toute opération utilisant un indice de tableaux peut aussi être réalisée grâce à des pointeurs.
La version utilisant des pointeurs sera , en général, plus rapide , mais , au moins pour les non initiés , quelque peu difficile à saisir immédiatement .
Pierre
Messages : 244
Inscription : ven. 23/janv./2004 20:29
Localisation : 77 (Région parisienne)

Message par Pierre »

ah, OK
je faisais un petit jeu qui utilisait les tableaux (super mario(il est déja bien avancé)), ben maintenant ça va être les pointeurs!!!
déja que j'avais superbement bien optimié mon jeu, et puis qu'il tournait super bien, et ben ça va être encore mieux!!!
encore merci!!
mais c'est quoi passer la procedure comme argument???
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

ben un argument d'une procédure , c'est les données que tu places entre les parenthèses

Code : Tout sélectionner

Procedure MaProcedure(Argument1,Argument2)
et quand on dit que l'on ne peut pas passer une structure en argument à une procedure , ça veut dire que tu ne peux mettre une structure directement comme argument , mais qu'il faut passer par un pointeur

Code : Tout sélectionner

Structure MaStructure
   Var1.l
   Var2.f
EndStructure

Essai.MaStructure

Procedure MaProcedure(*Argument1.MaStructure)
   *Argument1\Var1 = 10
   *Argument1\Var2 = 3.78
EndProcedure


Debug"Avant appel de la procedure" 
Debug Essai\Var1
Debug Essai\Var2
MaProcedure(@Essai)
Debug"Après appel de la procedure" 
Debug Essai\Var1
Debug Essai\Var2
Pierre
Messages : 244
Inscription : ven. 23/janv./2004 20:29
Localisation : 77 (Région parisienne)

Message par Pierre »

merci!
Image
Pierre
Messages : 244
Inscription : ven. 23/janv./2004 20:29
Localisation : 77 (Région parisienne)

Message par Pierre »

bon je fais des petits tests pour apprendre a me servir des pointeurs.
bon donc j'alloue avec allocatememory(...) la mémoire en octet dont j'ai besoin, c'est bien ça?
puis je fais des test en stockant des mot, des chiffres...
et j'ai vu que dans allocatememory(...) que je mette 1000 ou 1 ou n'importe quel autre chiffre (a par des chiffres négatif ou 0 (normal)) ça change rien!!!

donc ça:

Code : Tout sélectionner

*mem = AllocateMemory(1);une zone de mémoire
test$ = "je fais un test avec les pointeurs"
*mem = @test$
Debug PeekS(*mem, Len(test$))
ou ça

Code : Tout sélectionner

*mem = AllocateMemory(1000);une zone de mémoire
test$ = "je fais un test avec les pointeurs"
*mem = @test$
Debug PeekS(*mem, Len(test$))
ça me donne le même résultat!!
dans un autre test j'ai mis d'autres valeur dans le pointeur, j'ai alloué d'autre zone de mémoire et j'ai fais des tas d'autres trucs
ça a rien changé, pas de données écrasées par d'autres... rien!
donc y sert a quoi allocatememory(...), parce que je lui met 1 comme valeur et je stocke tout ce que je veut dedans!
si je suis pas assez clair faut le dire!
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Et encore plus fort :

Code : Tout sélectionner

test$ = "je fais un test avec les pointeurs" 
*mem = @test$ 
Debug PeekS(*mem, Len(test$))

en fait c'est test$ qui réserve la mémoire et quand tu fais *mem= @test$ , *mem pointe sur l'adresse de cette zone mémoire
Pierre
Messages : 244
Inscription : ven. 23/janv./2004 20:29
Localisation : 77 (Région parisienne)

Message par Pierre »

ah OK,
mais avec ça aussi je suis obligé de mettre allocatememory(..) et ça fait pareil:

Code : Tout sélectionner

*mem = AllocateMemory(1);une zone de mémoire
test$ = "je fais un test avec les pointeurs"
PokeS(*mem, test$)
Debug PeekS(*mem, Len(test$))
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

oui mais dans ce cas tu risques de planter car tu écris en dehors de la zone mémoire réservée !!
Pierre
Messages : 244
Inscription : ven. 23/janv./2004 20:29
Localisation : 77 (Région parisienne)

Message par Pierre »

c'est sur que j'aurais pas fait ça dans un programme,
mais c'était juste pour savoir parce que ça marchait sans histoire
Ok merci!!!
Image
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

Fred a écrit :Pour vraiment jouer avec les pointeurs, il faut utiliser une structure. Et ca donne ceci:

Code : Tout sélectionner

Structure MonOctet
  Octet.b
EndStructure

Dim Tableau.b(45)

Tableau.b(0) = 1
Tableau.b(1) = 2
Tableau.b(2) = 3
Tableau.b(3) = 4


; on affiche le tableau original

For k=0 To 4
  Debug Tableau(k)
Next

Debug "-----------------"

; et maintenant, les choses serieuses
;
*Pointeur.MonOctet = @Tableau() ; Adresse de debut du tableau

*Pointeur\Octet = 4  ; Ca correspond a la case 0 du tableau
*Pointeur+1  ; On se deplace de 1 octet
*Pointeur\Octet = 5 ; Ca correspond a la case 1 du tableau
*Pointeur+2
*Pointeur\Octet = 6 ; Ca correspond a la case 3 du tableau

; et on le prouve

For k=0 To 4
  Debug Tableau(k)
Next
L'avantage de cette methode par rapport a peek/poke, c'est sa rapidité. Amusez-vous bien :)
je ressors ce vieux post ,parce que j'étais en train de reprendre un code en utilisant cette méthode à la place des peek et des poke , et puis je me suis dit qu'avant d'aller plus loin , il serait bon de faire un test du gain en vitesse que je peux espérer , alors j'ai repris ce code et j'ai ajouté quelques peek et poke
et finalement ,ce sont les peek et les poke qui sont plus rapides , de peu , alors disons qu'il y a égalité , alors est-ce que c'est mon test qui n'est pas probant ? ou il y a bien égalité entre les deux méthodes ??

[EDIT]
j'avais encore un dernier doute , je viens d'ajouter le dernier test en utilisant le tableau , ben c'est encore avec ça que c'est le plus rapide !
alors je dois remplacer mes peek et mes poke par un tableau ??

Code : Tout sélectionner

Structure Monlong 
  Long.l 
EndStructure 

Dim Tableau.l(45) 

Tableau(0) = 1 
Tableau(1) = 2 
Tableau(2) = 3 
Tableau(3) = 4 


; on affiche le tableau original 

For K=0 To 3 
  Debug Tableau(K) 
Next 

Debug "-----------------" 

; et maintenant, les choses serieuses 
; 
tps=ElapsedMilliseconds() 
For i=1 To 10000000 
  *Pointeur.Monlong = @Tableau() ; Adresse de debut du tableau 
  *Pointeur\Long = 5 
  *Pointeur+4  
  *Pointeur\Long = 6 
  *Pointeur+4 
  *Pointeur\Long = 7 
  *Pointeur+4 
  *Pointeur\Long = 8 
Next i 
total1=ElapsedMilliseconds()-tps 

For K=0 To 3 
  Debug Tableau(K) 
Next 
Debug total1 
Debug "-----------------" 
tps=ElapsedMilliseconds() 
For i=1 To 10000000 
  Adresse=@Tableau(); Adresse de debut du tableau 
  PokeL(Adresse,8) 
  PokeL(Adresse+4,7) 
  PokeL(Adresse+8,6) 
  PokeL(Adresse+12,5) 
Next i 
total2=ElapsedMilliseconds()-tps 

For K=0 To 3 
  Debug Tableau(K) 
Next 
Debug total2
Debug "-----------------" 
tps=ElapsedMilliseconds() 
; pour faire des additions aussi avec le tableau 
For i=1 To 10000000 
  index=0 ;histoire d'avoir des calculs à faire ici aussi 
  Tableau(index) = 1 
  Tableau(index+1) = 2 
  Tableau(index+2) = 3 
  Tableau(index+3) = 4 
Next i 
total3=ElapsedMilliseconds()-tps 

For K=0 To 3 
  Debug Tableau(K) 
Next 
Debug total3
Debug "-----------------" 
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Si tu fais un test avec une structure contenant plus d'un élément, les pointeurs vont être plus rapide. C'est vrai que les Peek et Poke sont plus vite assimilable mais avec dès qu'on emploie une structure, il vaut mieux employer les pointeurs qui deviennent plus simple et plus compréhensible pour récupérer une valeur , surtout par les API.
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

ok , je vais encore faire des tests pour voir dans quels cas c'est vraiment plus rapide, je vais donc tester avec des structures comportant plus d'éléments .J'ai encore pas tout assimilé dans ce domaine , ça ne me fera pas de mal de faire ces manipulations :)

et ensuite , il faudra que j'analyse si ça va vraiment m'apporter quelque chose dans le code que j'étais en train de modifier . Apparemment c'est au cas par cas , parfois le tableau est encore la solution la plus rapide.

Si quelqu'un a des exemples plus concrets à proposer , ça m'intéresse .
Répondre