AppendMemory

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

AppendMemory

Message 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 ?
Guimauve
Messages : 1015
Inscription : mer. 11/févr./2004 0:32
Localisation : Québec, Canada

Message 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.
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

J'ai regardé... mais sans plus. Aurais tu un petit exemple ?
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message 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)

Denis

Bonne Jounée à tous
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message 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)

Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Dernière modification par Dr. Dri le mar. 14/nov./2006 20:27, modifié 1 fois.
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message par brossden »

Oui.... C'est bien se casser la tête pour pas grand chose !! :roll:
Denis

Bonne Jounée à tous
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

Alors comment pourrais je faire pour que mes Append<Type> fonctionne ?
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message 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 ....
Denis

Bonne Jounée à tous
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message 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 !
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message 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 ! !
Denis

Bonne Jounée à tous
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message par lionel_om »

Je te conseille qd même un :

Code : Tout sélectionner

ProcedureReturn ReAllocateMemory(...)
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 :wink:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message 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  
brossden
Messages : 833
Inscription : lun. 26/janv./2004 14:37

Message 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 !
Denis

Bonne Jounée à tous
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message 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
Image
Répondre