[Pascal] -> Probleme de buffer ...

-> Probleme de buffer ... [Pascal] - Programmation

Marsh Posté le 12-05-2001 à 22:14:52    

Voilà une version en développement d'un petit projet de cryptage que je fais avec un pote
seulement on a un problème en créant un buffer avec un tableau. On aurait pu le faire avec
des pointeurs mais c'est pas censée être au programme donc on le fait en cste.
Voilà exactement le problème: Quand la proc encode est appellee de nombreuses fois durant
le deroulement du programme pas de probleme le tableau est vidé afin d'etre rempli à nouveau
par un blockread. Seulement quand le cryptage est fini, la personne retourne au menu (autre
proc), choisit de recrypter alors là on se tape un stack overflow au begin de encode.
Comme si le tableau n'avait pas été effacé lorsque l'on quitte la procédure. Si le tab est
mis en local, cela ne change rien, on aboutit au meme resultat alors que ce qui est en local
une fois sorti de la proc ne devrait plus exister...
Si on augmente la taille de la pile c pareil, alors si qq un de sympa pouvait nous filer un coup
de main ce serait cool, parce que pr l'instant le seul moyen de contourner le probleme c'est
de baisser la taille du tableau (faite pas gaffe au code un peu pourri j'avais qu'une alpha sous
la main).
 
 
 
 
 
 
{version 2 alpha3}
program morkitu;  
uses crt,dos;    
 
 
const
 
maxbuffer=60000;
 
min_char=30000;
 
 
type
 
filechar= file;    {filechar est un fichier qui est déclaré comme ne
                           contenant que des caractères }
filebyte=file of byte;      {filebyte lui est déclaré comme fichier composé
                           d'entiers de type byte}
 
tab_byte= Array [1..6] of byte;
 
tab_buf= array [1..maxbuffer] of Char;
 
 
.......
 
 
procedure encode(clef:string;var file1,file2: filechar;sizefil:longint);
{Cette procédure est chargée du cryptage (ou du décryptage, c'est pareil
étant donné que c'est un XOR) du fichier.On lui passe la clef, le fichier
à crypter, le temporaire et la taille du fichier.}
 
 var
 fileini:filebyte;
 hh,mm,ss,cent:word;
 buffer_size,reste_car,hh3,totsec,i,j,k:longint; {Déclaration de toutes nos variables locales}
 tempcar,car:char;
 lengthkey:integer;
 tab_options:tab_byte;
 buffer:tab_buf;
 
 
begin
assign(fileini,'morkitu.ini'); {On assigne le fichier physique à un nom
logique}
setfattr(fileini,archive); {On met l'attribut archive pour enlever la lecture
seule}
 
reset(fileini); {On ouvre le fichier pour le lire}
seek(fileini,1); {On place le curseur au deuxième élément}
 
for i:=1 to 5 do
 
begin
read(fileini,tab_options[i]);
{On lit les 5 options qui nous intéressent, c'est-à-dire l'affichage:
-de la position du curseur
-du pourcentage du fichier crypté
-du temps écoulé
-du temps estimé
-du temps restant}
end;
tab_options[6]:=tab_options[3] or tab_options[4] or tab_options[5];
 
close(fileini); {On ferme le fichier de configuration}
setfattr(fileini,readonly); {On protège le fichier en le mettant en lecture
seule}
 
 
gettime(hh,mm,ss,cent); {On récupère l'heure au format heures,minutes,
secondes,centièmes de secondes}
     hh3:=hh; {On passe hh à hh3 afin de le transformer en longint}
     totsec:=3600*hh3+mm*60+ss; {On fait le total en secondes des heures,
     minutes et secondes}
     lengthkey:=length(clef); {On stocke la longueur de la clef}
     clef:=copy(clef,(lengthkey div 2) +1,lengthkey -lengthkey div 2)+copy(clef,1,lengthkey div 2); {On coupe la clef en 2,
en mettant la première partie à la fin et la deuxième partie au début}
 
      for i:=1 to (lengthkey div 2) do {On inverse tous les caractères de la
       clef }
       begin
       tempcar:=clef[i];
       clef[i]:=clef[lengthkey+1-i];
       clef[lengthkey +1 -i]:=tempcar;
       end;
 
 
 
reste_car:=maxbuffer;
buffer_size:=1;
 
gotoxy(46,3);
write('(...searching buffer)');
 
if sizefil < min_char then
begin
reste_car:=sizefil;
buffer_size:=1;
end
else
begin
 
for i:=maxbuffer downto 1 do
 
 
begin
k:=sizefil mod i;
if (k<= reste_car) AND (i >= buffer_size) AND (k < min_char) then
begin
reste_car:=k;
buffer_size:=i;
end;
 
end;
end;
 
gotoxy(44,3);
write('1er buffer: ',buffer_size,' octet(s)      ');
 
reset(file1,buffer_size);
rewrite(file2,buffer_size);
 
  for i:=1 to (sizefil div buffer_size) do
  begin
               blockread(file1,buffer,1); {On lit un caractère}
 
      for k:=1 to buffer_size do
      begin
 
      j:=k mod lengthkey; {On vérifie la valeur du modulo}
                           if j=0 {Swi j est égale à 0}
                           then
                           begin
                           j:=lengthkey; {Alors j est égale à la longueur de la clef}
                           clef:=copy(clef,4,lengthkey-1)+copy(clef,1,3); {et on fait
                           une permutation de caractères en plaçant 3 caractères du
                           début à la fin}
      end;
      buffer[k]:=chr(ord(buffer[k]) xor ord(clef[j]));
 
               {L'opération logique XOR
               qui crypte le caractère lu. On fait un XOR entre la valeur
               ASCII du caractère lu dans le fichier et celle d'un des
               caractères de la clef}
               end;
 
 
encode_display(file1,sizefil,buffer_size,totsec,hh,tab_options);
 
 
           blockwrite(file2,buffer,1); {On écrit le caractère crypté dans le fichier
           temporaire}
 
           if keypressed {Si lors du cryptage une touche est pressée}
           then {alors on vérifie si c'est la touche Escape}
 
              if readkey=#27 then {Si c'est la cas}
              begin
              close(file1); {alors on ferme les 2 fichiers, on efface le
              temporaire et on appelle mainmenu}
              close(file2);
              erase(file2);
              mainmenu;
              end;
 
     end;
 
 
if reste_car <> sizefil then
begin
buffer_size:=1;
gotoxy(44,4);
write('2e  buffer: ',buffer_size,' octet');
reset(file1,buffer_size);
seek(file1,sizefil-reste_car);
reset(file2,buffer_size);
seek(file2,filesize(file2));
 
for i:=1 to reste_car do
  begin
               blockread(file1,buffer,1); {On lit un caractère}
 
 
 
        j:=i mod lengthkey; {On vérifie la valeur du modulo}
               if j=0 {Si j est égale à 0}
               then
               begin
               j:=lengthkey; {Alors j est égale à la longueur de la clef}
               clef:=copy(clef,4,lengthkey-1)+copy(clef,1,3); {et on fait
                une permutation de caractères en plaçant 3 caractères du
                début à la fin}
      end;
      buffer[1]:=chr(ord(buffer[1]) xor ord(clef[j]));
 
               {L'opération logique XOR
               qui crypte le caractère lu. On fait un XOR entre la valeur
               ASCII du caractère lu dans le fichier et celle d'un des
               caractères de la clef}
 
 
 
encode_display(file1,sizefil,buffer_size,totsec,hh,tab_options);
 
 
           blockwrite(file2,buffer,1); {On écrit le caractère crypté dans le fichier
           temporaire}
 
           if keypressed {Si lors du cryptage une touche est pressée}
           then {alors on vérifie si c'est la touche Escape}
 
              if readkey=#27 then {Si c'est la cas}
              begin
              close(file1); {alors on ferme les 2 fichiers, on efface le
              temporaire et on appelle mainmenu}
              close(file2);
              erase(file2);
              mainmenu;
              end;
 
     end;
 
end;
 
 
end;
 
 
 
..............
 
 
{Programme principal}
{Ouh lala qu'il est long !!! ;-)}
 
begin
{$M 65520,0,655360}
mainmenu; {On appelle juste mainmenu}
end.

 

[edit]--Message édité par Niglo--[/edit]

Reply

Marsh Posté le 12-05-2001 à 22:14:52   

Reply

Marsh Posté le 13-05-2001 à 18:20:22    

Personne ne veut me filer un petit coup de main ? :)

Reply

Marsh Posté le 14-05-2001 à 00:18:36    

Je suppose que la procédure "mainmenu" appelle la procédure "encode", or cette dernière appelle aussi la procédure "mainmenu" (après les "if readkey=#27 " ), il y a donc une méchante récursivité du style :
 
proc a
   appel proc b
fin proc
 
proc b
   appel proc a
fin proc
 
Dans ce cas les variables locales ne sont jamais détruites ...
 
J'espère que cela va résoudre le problème.
 
Salutations

Reply

Marsh Posté le 14-05-2001 à 02:35:34    

Merci bcp j'avais pas pensé à ça :)
J'essaierai de palier à ce prob pour voir ce que ça donne...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed