Compilation bizarre [Résolu]

Signaler
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
-
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
-
Salut,

(Sous Delphi 7)

Prenont le code suivant :

var
  sOut: array[0..255] of Char;
begin
  CopyMemory(@sOut, PChar('allo'), Length('allo') + 1);
  ShowMessage(sOut);
end;

CopyMemory prend en argument un pointeur sur la destination, un pointeur sur la source, et le nombre d'octets pointés par la source à copier dans la destination.
On copie donc 'allo' dedans + le zéro terminal, et on l'affiche dans une MessageBox.
Jusque là, rien de miraculeux, tout va bien. A moins que j'ai déjà fait une faute.

Mais si on modifie à peine ce code suivant et que l'on remplace anodinement 'allo' par 'a' :

var

  sOut: array[0..255] of Char;

begin

  CopyMemory(@sOut, PChar('a'), Length('a') + 1);

  ShowMessage(sOut);

end;

Cela n'affiche pas a, mais une exception de type violation d'accès...
En effet, le compilo considère 'a' comme un octet valant le code ascii du caractère a, met cette octet dans un integer, et pousse cette valeur... Et bien évidement, ce qui se trouve à l'adresse $61 n'est pas accessible...

Amusant

3 réponses

Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
Bonjour,

var
  sOut: array[0..255] of Char;
  P:PChar; // Obligatoirement une variable pour CopyMemory
begin
  //Nécessaire pour être sur de "vider" la zone
  Fillchar(sOut,sizeof(sOut),0); 
  P:='a';
  // @sOut ou @sOut[0], je prefère la seconde ;) 
  CopyMemory(@sOut[0], P, Length(P));
  ShowMessage(sOut);
end;

Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein
Messages postés
3874
Date d'inscription
mardi 8 mars 2005
Statut
Modérateur
Dernière intervention
7 novembre 2014
13
Bah merci de t'intéresser à mon cas WhiteHippo, même si ça me comble pas tout à fait... C'est vrai que ça fait pas logique de mettre une constante quand le compilo attend un pointeur, mais ça marche très bien avec 'allo'. Que le nombre de caractère dans une chaîne modifie le comportement du compilo, j'en reste pantois. M'enfin je valide car apparement personne n'aura de meilleur syntaxe/explication.
Messages postés
1154
Date d'inscription
samedi 14 août 2004
Statut
Membre
Dernière intervention
5 avril 2012
2
rt15,
Désolé de ne pas avoir répondu plus clairement la fois précédente.

Si tu voulais que cela fonctionne, il fallait préciser que 'a' n'est pas un caractère mais une chaine de caractères. Le transtypage en PChar transforme le caractère en un "entier" ( d'où l'adresse $61=97=code ASCII de la lettre a). C'est le même comportement que si tu écris Pointer(1234) qui te renverras alors comme adresse $1234.

Trois solutions possibles à ce problème :
  CopyMemory(@sOut, Pchar('a'#0), Length('a'));
  CopyMemory(@sOut, Pchar(string('a')), Length('a')); 
    Celle que je t'ai proposé précedemment.
 
N.B. dans tous les cas, il faudra initialisé le buffer de copie par
  Fillchar(sOut,sizeof(sOut),0); 

Cordialement.
<hr />"L'imagination est plus importante que le savoir." Albert Einstein