Compilation bizarre

Résolu
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 - 5 juil. 2007 à 08:59
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 - 6 juil. 2007 à 15:13
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

WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
5 juil. 2007 à 09:44
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
3
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
6 juil. 2007 à 08:41
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.
0
WhiteHippo Messages postés 1154 Date d'inscription samedi 14 août 2004 Statut Membre Dernière intervention 5 avril 2012 3
6 juil. 2007 à 15:13
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
0
Rejoignez-nous