Page 1 sur 1
Pointeur de chaines
Publié : lun. 23/mars/2009 16:47
par LavaLava
Salut,
je ne suis pas sur que cela soit un bug mais cela m'enbête un peu...
En fait, je devais convertir du texte de 2 liste chainée.
Pour ne pas écrire 2 procédures identiques (à par le nom de la liste chainée), j'ai voulut utiliser un pointeur...
Mais apparament, si la variable n'a pas été accédé ou initialisé une fois, le pointeur ne fonctionne pas.
Voici un exemple simple pour mettre cela en évidence :
Code : Tout sélectionner
Procedure Change( *A$ )
*A$ = "Changed"
EndProcedure
Global B$
Change( @B$ )
Debug B$ ; => ""
B$ = "Main"
Change( @B$ )
Debug B$ ; => "Canged"
End
Merci
Publié : lun. 23/mars/2009 19:57
par case
cela me semble normal,
un simple global b$="" résout le problème
sans vouloir dire de bêtises, je suppose que faire un
global b$
définit simplement la variable comme étant globale, mais elle n'est pas initialisée et n'a donc pas d'adresse physique en mémoire.
un global b$="" l'initialise comme étant vide mais lui réserve tout de même une place en mémoire
Publié : lun. 23/mars/2009 21:04
par LavaLava
Salut,
Effectivement, je ne sais si c'est normal ou pas, mais les variables de type string n'ont pas d'adresse définite lors de leur déclaration par un global.
Par contre c'est le cas pour les variables numériques...
Cependant, le fait d'initialiser les variables de type string n'a pas résolu mon problème ...
Exemple :
Code : Tout sélectionner
Procedure Change( *A$, *B$ )
*A$ = "Changed A"
*B$ = "Changed B"
EndProcedure
Global AA$ = "", BB$ = ""
Change( @AA$ , @BB$)
Debug AA$ + " " + BB$
Change( @AA$ , @BB$)
Debug AA$ + " " + BB$
End
Chez moi, XP Sp3 et Pb 4.3, cela me génere une erreur "Invalid memory access" lors du second appel de la procédure ...
Publié : lun. 23/mars/2009 21:25
par cha0s
Code : Tout sélectionner
Procedure Change( *A, *B)
PokeS(*A, "Changed A")
PokeS(*B, "Changed B")
EndProcedure
Global AA$ = Space(Len("Changed A")+1), BB$ = Space(Len("Changed B")+1)
Change( @AA$ , @BB$)
Debug AA$ + " " + BB$
Change( @AA$ , @BB$)
Debug AA$ + " " + BB$
End
si la mémoire n'est pas alloué tu risque de tomber sur une zone de mémoire interdite a ton programme car tu dépasse la taille initiale.
Publié : mar. 24/mars/2009 1:04
par LavaLava
Justement, mon but est de pouvoir modifier le contenue, et donc la longueur, d'une variable de type string en ne connaissant que son adresse !
Ce que je comprends pas c'est que, grâce à son adresse, je puisse lire le contenu de la variable mais pas le modifier...
Code : Tout sélectionner
Structure Test
S$
EndStructure
Procedure Change( *V$ )
Debug "*V$=" + *V$
Debug "@*V$=" + Str( @*V$ )
*V$ = *V$ + *V$
EndProcedure
Global AA.Test, BB.Test
AA\S$ = "ABCDEF"
Debug "Global @AA\S$=" + Str( @AA\S$ )
Change( @AA\S$ )
Change( @AA\S$ )
Debug "Result AA=" + AA\S$
Debug ""
BB\S$ = "IJKLMN"
Debug "Global @BB\S$=" + Str( @BB\S$ )
Change( @BB\S$ )
Change( @BB\S$ )
Debug "Result BB=" + BB\S$
Publié : mar. 24/mars/2009 1:34
par cha0s
c'est une question d'allocation mémoire quand tu initialise ta chaine elle prend telle taille en octet et cela ne changera pas si tu touche directement a l'adresse mémoire car le compilateur ne va pas allouer de la mémoire par l'opération du saint esprit.
Mais il y a une solution magique a cela c'est allocatememory(sizeof(char)*(longeur de chaine + 1)) a l'initialisation et reallocatememory(sizeof(char)*(longeur de la nouvelle chaine + 1))
Il ne faut pas oublier que l'adresse d'une chaine c'est un pointeur vers un pointeur (vous avez suivit ? :p) comme avec mysql pour les connaisseur on pointe vers le pointeur du résultat xD
Publié : mar. 24/mars/2009 11:55
par LavaLava
Salut,
C'est probalbement absurde au sens strict de la programmation, mais hormis le saint esprit, je m'attendais à ce que le PB gère la nouvelle taille de la mémoire ...
Car en fait, par un pointeur et une structure on peut lire et écrire dans l'espace mémoire allouée à une variable de type chaine, mais si on écrit un caractère de trop on plante !
A moins qu'il existe une syntaxe que j'ai pas encore trouvée ...
@+
Publié : sam. 28/mars/2009 23:04
par Ollivier
Après un petit passage par l'option ASM, j'ai isolé la macro qui modifie une chaîne en fonction d'une autre.
L'instruction "LEA reg, [expr]" en ASM transfert le résultat de expr dans reg. Or expr c'est une expression créée lors de la compilation.
ça rejoint l'explication de ChaOs.
Code : Tout sélectionner
Macro InitStrCopy()
Define XXX.S
XXX + ""
EndMacro
Macro SetString(Cible, Source)
! PUSH dword [_PB_StringBasePosition]
! MOV edx,dword [v_#Source]
! CALL _SYS_CopyString@0
! LEA ecx,[v_#Cible] ; << *** Le souci est ici *** <<
! POP edx
! CALL SYS_AllocateString
EndMacro
InitStrCopy()
Define X.S
Define Y.S = "Quartet"
SetString(X, Y)
Debug X