copymemory et pointeur

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

copymemory et pointeur

Message 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
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message 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
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message 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.
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message 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))
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Hardy le problème est copymemory, situ fais Debug a\Nom, dans ton cas il n'y a pas de problème.
hardy
Messages : 333
Inscription : mer. 02/juin/2004 13:19
Localisation : Tours

Message par hardy »

Je sais. C'était juste pour répondre au soldat inconnu. :D
filperj
Messages : 395
Inscription : jeu. 22/janv./2004 1:13

Message 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

Le chaos l'emporte toujours sur l'ordre
parcequ'il est mieux organisé.
(Ly Tin Wheedle)
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message 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
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message 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
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message par Dräc »

D'ac, ca me va :)
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message 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.
Image
Dräc
Messages : 526
Inscription : dim. 29/août/2004 0:45

Message par Dräc »

Effectivement, c'est du C et une suggestion intéressante :wink:
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

Message 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
lionel_om
Messages : 1500
Inscription : jeu. 25/mars/2004 11:23
Localisation : Sophia Antipolis (Nice)
Contact :

Message 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:
Webmestre de Basic-univers
Participez à son extension: ajouter vos programmes et partagez vos codes !
erix14
Messages : 480
Inscription : sam. 27/mars/2004 16:44
Contact :

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