Page 1 sur 2
AppendMemory
Publié : mar. 14/nov./2006 10:19
par Progi1984
Voilà, mon pb est là :
J'ai une zone mémoire (AllocateMemory et PokeX pour lui attribuer du contenu).
Mais je souhaiterais ajouter qqch à la fin de la zone mémoire précédement crée.
Quelqu'un aurait un exemple pour me montrer comment faire, SVP ?
Publié : mar. 14/nov./2006 13:44
par Guimauve
Dis donc est-ce que tu as regardé du coté de ReAllocateMemory() ?
Il semble que c'est possible d'agrandir une zone mémoire déja alloué. Et donc d'écrire plus d'information dans la zone mémoire.
Publié : mar. 14/nov./2006 14:34
par Progi1984
J'ai regardé... mais sans plus. Aurais tu un petit exemple ?
Publié : mar. 14/nov./2006 16:47
par brossden
Voila pour le petit exemple :
Code : Tout sélectionner
;Allocation de 1000 octets au pointeur *mem
*mem =AllocateMemory(1000)
;Attribution de la valeur 65 (caractère "A") de ces 1000 octets
For n=0 To 999
PokeC(*mem+n,65)
Next
;Lecture de 20 octets à partir du 900 ième caractère de *mem
Debug PeekS(*mem+900,20)
Debug " "
;Réallocation de 1500 octets au pointeur *mem
*mem = ReAllocateMemory(*mem,1500)
;Attribution de la valeur 66 (caractère "B") de ces 500 octets supplémentaires
For n=1000 To 1500
PokeC(*mem+n,66)
Next
;Lecture de 20 octets à partir du 990 ième caractère de *mem
Debug PeekS(*mem+990,20)
; Donc 10 "A" ( de 990 à 1000 ) suivit de 10 "B" (1000 à 1010)
Publié : mar. 14/nov./2006 16:57
par Progi1984
Merci, je viens de réaliser la fonction que je souhaitais :
Code : Tout sélectionner
Procedure AppendB(*Memory, Byte.b)
ReAllocateMemory(*Memory,MemorySize(*Memory)+1)
PokeB(*Memory+MemorySize(*Memory)-1, Byte)
EndProcedure
Procedure AppendC(*Memory, Character.c)
CompilerIf #PB_Compiler_Unicode = 1
ReAllocateMemory(*Memory,MemorySize(*Memory)+2)
PokeC(*Memory+MemorySize(*Memory)-2, Character)
CompilerElse
ReAllocateMemory(*Memory,MemorySize(*Memory)+1)
PokeC(*Memory+MemorySize(*Memory)-1, Character)
CompilerEndIf
EndProcedure
Procedure AppendW(*Memory, Word.w)
ReAllocateMemory(*Memory,MemorySize(*Memory)+2)
PokeW(*Memory+MemorySize(*Memory)-2, Word)
EndProcedure
Procedure AppendL(*Memory, Long.l)
ReAllocateMemory(*Memory,MemorySize(*Memory)+4)
PokeL(*Memory+MemorySize(*Memory)-4, Long)
EndProcedure
Procedure AppendF(*Memory, Float.f)
ReAllocateMemory(*Memory,MemorySize(*Memory)+4)
PokeF(*Memory+MemorySize(*Memory)-4, Float)
EndProcedure
Procedure AppendQ(*Memory, Quad.q)
ReAllocateMemory(*Memory,MemorySize(*Memory)+8)
PokeQ(*Memory+MemorySize(*Memory)-8, Quad)
EndProcedure
Procedure AppendD(*Memory, Double.d)
ReAllocateMemory(*Memory,MemorySize(*Memory)+8)
PokeD(*Memory+MemorySize(*Memory)-8, Double)
EndProcedure
Procedure AppendS(*Memory, String.s)
ReAllocateMemory(*Memory,MemorySize(*Memory)+Len(String))
PokeS(*Memory+MemorySize(*Memory)-Len(String), String)
EndProcedure
*mem =AllocateMemory(10)
For n=0 To 9
PokeC(*mem+n,65)
Next
Debug PeekS(*mem)
Debug "=========================="
For n=9 To 20
AppendC(*mem, 66)
Next
Debug PeekS(*mem)
Publié : mar. 14/nov./2006 17:23
par Dr. Dri
ATTENTION !!!
ReAllocateMemory n'alloue pas forcément la mémoire à la même adresse !!
Code : Tout sélectionner
buffer = AllocateMemory(1024)
Debug Hex(buffer)
buffer = ReAllocateMemory(buffer, 1024*1024)
Debug Hex(buffer)
L'allocation peut même échouer
Code : Tout sélectionner
buffer = AllocateMemory(1024)
Debug Hex(buffer)
buffer = ReAllocateMemory(buffer, 1024*1024*1024)
Debug Hex(buffer)
Dri
Publié : mar. 14/nov./2006 20:08
par brossden
Oui.... C'est bien se casser la tête pour pas grand chose !!

Publié : mer. 15/nov./2006 9:12
par Progi1984
Alors comment pourrais je faire pour que mes Append<Type> fonctionne ?
Publié : mer. 15/nov./2006 15:12
par brossden
Solution 1
Allouer une grande taille mémoire à un pointeur, et redistribution des de cette mémoire en segments en fonction des mémoires plutot que de lui réaffecter un ou deux octets de plus !
Solution 2
Allouer autant de pointeur qu'il est necessaire.
Solution 3
Ecrire dans des mémores et si besoin, utiliser les adresses mémoires pour pouvoir jouer avec les peek et poke !!
et là ne s'arrêtent pas les solutions ....
Publié : mer. 15/nov./2006 15:47
par Progi1984
Disons que mon code fonctionne parfaitement, je l'ai testé hier soir dans un programme en essayant de le faire fonctionner un max et je n'ai aucun problème au final avec mon WriteData !
Publié : mer. 15/nov./2006 16:21
par brossden
On est jamais mieux servi que par soi même donc si ton algo te satisfait tout est parfait.
Tu n'est pas là pour nous faire plaisir, alors désolé si je t'ai énervé ce n'était pas mon intention ! !
Publié : mer. 15/nov./2006 16:22
par lionel_om
Je te conseille qd même un :
Car y'a de grandes chances que l'adresse de la zone mémoire change dès que tu utilise plusieurs fois ton Append{?} sur une même zone mémoire

Publié : mer. 15/nov./2006 16:26
par Progi1984
@brossden : j'essaie juste d'avoir un code le plus sur possible ! Tu ne m'as pas du tout énervé
@All : Et si, je remplace mes procédures par des macros, est ce que cela ne serait pas sur genre
Code : Tout sélectionner
Procedure AppendB(*Memory, Byte.b)
ReAllocateMemory(*Memory,MemorySize(*Memory)+1)
PokeB(*Memory+MemorySize(*Memory)-1, Byte)
EndProcedure
; remplacé par
Macro AppendB(Memory, Byte)
ReAllocateMemory(Memory,MemorySize(Memory)+1)
PokeB(Memory+MemorySize(Memory)-1, Byte)
EndMacro
Publié : mer. 15/nov./2006 17:36
par brossden
Ecoute je vais te donner une solution mais j'ignore si j'ai bien pigé ton problème.
Je pars le principe qie tu veux empiler des valeurs les une derrières les autres et qui sont parfois chaine parfois quad word ou même bit.
Voici ma solution en admettant pour cet exemple que tu ne depasseras jamais une valeur de 1Mo
Code : Tout sélectionner
Global *Offset, *Point
*Offset = AllocateMemory(105000)
*Point = *Offset
Debug *Offset
Procedure AppendS(Chaine.s)
Lg=Len(Chaine)
PokeS(*Offset,Chaine,Lg)
*Offset+Lg
EndProcedure
Procedure AppendD(Valeur.d)
PokeD(*Offset,Valeur)
*Offset+8
EndProcedure
Procedure AppendQ(Valeur.q)
PokeQ(*Offset,Valeur)
*Offset+8
EndProcedure
Procedure AppendF(Valeur.f)
PokeF(*Offset,Valeur)
*Offset+4
EndProcedure
Procedure AppendL(Valeur.l)
PokeL(*Offset,Valeur)
*Offset+4
EndProcedure
Procedure AppendW(Valeur.w)
PokeW(*Offset,Valeur)
*Offset+2
EndProcedure
Procedure AppendCAsc(Valeur.c)
PokeC(*Offset,Valeur)
*Offset+2
EndProcedure
Procedure AppendUni(Valeur.c)
PokeC(*Offset,Valeur)
*Offset+1
EndProcedure
Procedure AppendB(Valeur.b)
PokeB(*Offset,Valeur)
*Offset+1
EndProcedure
;Ici ton code ..........
;par exemple :
for n=1 to 1000
AppendS("Toto")
AppendD($FF1234EF1B5C8D9E)
AppendQ($102158F5E6F51A75)
AppendF(325.158)
AppendL(6589988474887)
AppendW(32000)
AppendCAsc(255)
AppendB(12)
Next
;............... etc...
;Pour finir
OpenFile(1,"c:\append1.txt")
WriteData(1,*Point,*Offset-*Point)
CloseFile(1)
Il faut savoir aussi que tu peux t'éviter d'ecrire toutes ces procedures
et écrire directement :
Code : Tout sélectionner
Global *Offset, *Point
*Offset = AllocateMemory(105000)
*Point = *Offset
For n=1 to 1000
PokeS(*Offset,"Toto",4) : *Offset+4
PokeD(*Offset,$FF1234EF1B5C8D9E) : *Offset+8
PokeQ(*Offset,$102158F5E6F51A75) : *Offset+8
PokeF(*Offset,325.158) : *Offset+4
PokeL(*Offset,6589988474887) : *Offset+4
PokeW(*Offset,32000) : *Offset+2
PokeC(*Offset,255) : *Offset+1
PokeB(*Offset,2) : *Offset+1
Next
OpenFile(1,"c:\append2.txt")
WriteData(1,*Point,*Offset-*Point)
CloseFile(1)
La deuxième solution à toutes mes voix cat le plus cours est souvent le plus rapide !
Test ces deux softs tu veras que le resultat est identique !
Publié : mer. 15/nov./2006 19:42
par Flype
@brossden
105000 c'est 105Ko, pas 1Mo.
c'est juste pour te charrier parce que ta facon de faire est selon moi la meilleure. enfin, au vu de ce que progi cherche à faire.
si les procédures de progi fonctionnent c'est de la chance. probablement parce qu'ici les quantités de mémoire allouées sont toutes petites.
progi alloue seulement 10 octets puis monte à 11, 12, 13, ... octets. peut etre que windows alloue direct un bloc de 1024 octets minimum en interne. du coup çà fonctionne mais c'est vraiment dangereux (enfin dangereux, c'est pas la fin du monde non plus).
la doc purebasic dit bien qu'il faut tenir compte du nouveau pointeur renvoyé par ReAllocateMemory().
Syntaxe
*MemoryID = ReAllocateMemory(*MemoireID, Taille)
Description
Alloue (si le paramètre *MemoroireID est 0) ou re-alloue une zone continue de mémoire de la Taille spécifiée (en octets). Si la zone de mémoire était déjà allouée, alors son ancien contenu est conservé. Si la quantité de mémoire demandée est disponible, *MemoryID contiendra l'adresse de début de la zone mémoire, ou 0 si la zone n'a pu être allouée (dans ce cas, l'ancienne zone mémoire est toujours valide).
Note: Toutes les zones mémoire créées sont automatiquement libérées à la fin du programme.
d'ailleurs il y a une petite coquille ici : *MemoroireID