Page 1 sur 2

copymemory et pointeur

Publié : sam. 22/janv./2005 12:02
par nico
Pour moi, il y a un problème, mais je suis méfiant; je ne comprends pas pourquoi je perds les informations.

Code : Tout sélectionner

Structure liste 
  *suivant.liste
  *precedent.liste 
  Nom.s
  age.l
EndStructure 

Global *Pointeur_debut.liste
Global agenda.liste  

Procedure ajoute(*ajouter.liste)
  *nouveau=AllocateMemory(SizeOf(liste))
  CopyMemory(*ajouter.liste,*nouveau,SizeOf(liste))
  *Pointeur_debut.liste=*nouveau 
EndProcedure

agenda\Nom="david"
agenda\age=10
ajoute(@agenda)

Debug *Pointeur_debut\Nom 
Debug *Pointeur_debut\age

agenda\Nom="nicolas"
agenda\age=11
; curieux, je perds mes informations
Debug *Pointeur_debut\Nom 
Debug *Pointeur_debut\age

Publié : sam. 22/janv./2005 12:13
par Le Soldat Inconnu

Code : Tout sélectionner

Structure liste 
  *suivant.liste 
  *precedent.liste 
  Nom.s 
  age.l 
EndStructure 

Debug SizeOf(liste)
ta structure fait 16 soit 4 long

le prob est que je sias pas comment est stocké le string dans une structure mais en tous cas, pas directement dedans
en tous cas, j'ai déjà buté sur ce problème alors si quelqu'un à une solution

Publié : sam. 22/janv./2005 12:31
par nico
La copie s'effectue correctement, seulement si on modifie la structure que l'on a copié au départ, cela à une incidence sur le résultat précédent.

nom fait partie d'une structure donc son adresse ne change pas au cours du programme alors que dans le cas contraire oui.

Ce problème avait été discuté sur le Forum Anglais (il y a quelque temps maintenant) et Fred avait fait la correction.

J'ai repris l'exemple qui avait été posté et effectivement je retrouve l'erreur.

Publié : sam. 22/janv./2005 12:38
par hardy
le prob est que je sias pas comment est stocké le string dans une structure mais en tous cas, pas directement dedans
en tous cas, j'ai déjà buté sur ce problème alors si quelqu'un à une solution

Code : Tout sélectionner

Structure liste
  *suivant.liste
  *precedent.liste
  Nom.s
  age.l
EndStructure
a.liste
a\nom="Poulenc"
debug peeks(peekl(@a+8))

Publié : sam. 22/janv./2005 12:42
par nico
Hardy le problème est copymemory, situ fais Debug a\Nom, dans ton cas il n'y a pas de problème.

Publié : sam. 22/janv./2005 18:44
par hardy
Je sais. C'était juste pour répondre au soldat inconnu. :D

Publié : sam. 22/janv./2005 21:42
par filperj
J'aurais vu ça comme ça, je sais pas si ça fait avancer le schmilblick...

Code : Tout sélectionner


Structure entree_agenda
  Nom.s
  age.l
EndStructure

Procedure CopieEntree(*src.entree_agenda,*dst.entree_agenda)
  *dst\Nom=*src\Nom  ;<- seul façon stable de copier une chaîne de structure à structure, à ma connaissance
  *dst\age=*src\age
EndProcedure

Structure liste
  *suivant.liste
  ;*precedent.liste <- inutilisé pour l'instant
  entree.entree_agenda
EndStructure

Global *Pointeur_debut.liste
Global agenda.entree_agenda

Procedure ajoute(*ajouter.entree_agenda)
  *nouveau.liste=AllocateMemory(SizeOf(liste))
  CopieEntree(*ajouter,@*nouveau\entree)
  *nouveau\suivant=*Pointeur_debut
  *Pointeur_debut.liste=*nouveau
EndProcedure

agenda\Nom="david"
agenda\age=10
ajoute(@agenda)

Debug *Pointeur_debut\entree\Nom
Debug *Pointeur_debut\entree\age

agenda\Nom="nicolas"
agenda\age=11
; curieux, je perds mes informations
Debug *Pointeur_debut\entree\Nom
Debug *Pointeur_debut\entree\age


Publié : mar. 24/janv./2006 11:52
par Dräc
@Fred : Avec la v4, peut-on espérer utiliser CopyMemory sur une structure comportant des variables typées string ?

Mon objectif est d’avoir une seule fonction permettant de dupliquer des données, sinon on est obligé (voir exemple de filperj) d’en créer autant que de structures différentes (ayant des string)

Code : Tout sélectionner

Procedure.l Duplicate (*src.l, size.l)
  *new = AllocateMemory(size)
  CopyMemory(*src, *new, size)
  ProcedureReturn *new
EndProcedure

Publié : mar. 24/janv./2006 12:00
par Dr. Dri
CopyMemory c'est CopyMemory... Faudrait plutôt une commande PB "CopyStructure" qui gèrerait ca automatiquement... C'est à dire qui serait adaptée à la structure au moment de la compilation comme le font les listes chainées...

Dri

Publié : mar. 24/janv./2006 12:02
par Dräc
D'ac, ca me va :)

Publié : mar. 24/janv./2006 12:03
par Flype
lorsque je rencontre ce type de problème (classique) je fais comme en C.

Code : Tout sélectionner

Structure liste 
  *suivant.liste 
  *precedent.liste 
  Nom.s 
  age.l 
EndStructure
converti ainsi :

Code : Tout sélectionner

#MaxChar = 64
Structure liste 
  *suivant.liste 
  *precedent.liste 
  Nom.b[#MaxChar] 
  age.l 
EndStructure
Comme çà CopyMemory() fonctionne sans problème. Inconvénient, faire des PeekS() et des PokeS(). Mais quand on cache la réalisation dans des procédures bien faites et explicites çà roule tout seul.

Ceci dit, une copie en natif d'une structure serait effectivement l'idéal.

Publié : mar. 24/janv./2006 12:14
par Dräc
Effectivement, c'est du C et une suggestion intéressante :wink:

Publié : mar. 24/janv./2006 16:41
par erix14
Inconvénient, faire des PeekS() et des PokeS().
Non, il suffit de mettre un champ Nom.s et de le faire pointer sur un champ DataNom.b[64] de la structure.
#MaxCharNom = 64
Structure liste
*suivant.liste
*precedent.liste
Nom.s
DataNom.b[ #MaxCharNom ]
age.l
EndStructure

MaListe.liste
PokeL (@MaListe+8,@MaListe\DataNom)

MaListe\Nom = "Erix14"
Debug MaListe\Nom

Publié : mar. 24/janv./2006 16:49
par lionel_om
Bah pour le champ "nom" c'est un pointeur sur une chaine de caractères (char*).
Donc faut faire un deuxième allocateMemory pour le string et modifier le champs "nom".
Je vois pas où est le problème. C'est normal que ca le fasse pas automatiquement. L'idée de CopyStructure est bonne.

Du moins c'est la manip que je fais dans ma librairie de listes chaînées : Liib Vector :wink:

Publié : mar. 24/janv./2006 17:20
par erix14
@lionel_om: tu ne trouves pas que la méthode évoquée est plus simple que la tienne ?
#MaxCharNom = 64
Structure liste
*suivant.liste
*precedent.liste
Nom.s
DataNom.b[ #MaxCharNom ]
age.l
EndStructure

MaListe.liste
PokeL (@MaListe+8,@MaListe\DataNom)

MaListe\Nom = "Erix14"
Debug MaListe\Nom

Maliste2.liste
PokeL (@Maliste2+8,@Maliste2\DataNom)

CopyMemory (@MaListe,@Maliste2,SizeOf(liste))
Debug Maliste2\Nom