[Delphi]Memoryblock opzoeken binnen ander memoryblock

Pagina: 1
Acties:

  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 22:57
Ik heb twee memoryblocken van 4096 bytes. Ik weet dat de twee blokken elkaar deels overlappen. nu ben ik op zoek naar het beginpunt van die overlapping.

code:
1
2
3
4
5
6
<-------------memoryblock1-------------->
               <-------------memoryblock2-------------->
<.............>
     ^
gezochte
 offset.


Zoeken op memory, search en delphi levert me allemaal geheugenspelletjes op.

Zelf wil ik de betreffende functie wel gaan schrijven, maar ik denk dat zo'n functie al tijden lang bestaat. Weet iemand waar?

  • Bergen
  • Registratie: Maart 2001
  • Laatst online: 18-08 10:58

Bergen

Spellingscontroleur

Het begintpunt van de overlapping is toch gewoon het beginpunt van block 2? Die offset kun je gewoon met addr() opzoeken. Of bedoel je dat niet? :?

[ Voor 34% gewijzigd door Bergen op 22-03-2003 00:03 ]


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 22:57
Nee, dat bedoel ik niet. Je kan het vergelijken met twee strings. De eerste string bevat 'a'..'q' en de tweede is een geheel andere string met de inhoud 'j'..'z' en wat ik zoek is 10 omdat de tekst 'j'..'q' uit string twee begint op plaats 10 van string1.

Alleen dan met memoryblokken.

Ik hoop dat dit duidelijker is.

  • LordLarry
  • Registratie: Juli 2001
  • Niet online

LordLarry

Aut disce aut discede

Ik denk niet dat hier een functie van bestaat. Het komt ook weinig voor denk ik. Wat wel voorkomt is dat je de positie van een stuk geheugen (string meestal) in een ander stuk gehuegen moet worden gezocht, maar bij jouw hoeft het niet eens compleet te zijn. Ik denk dat je het toch echt zelf moet schrijven.

We adore chaos because we like to restore order - M.C. Escher


  • Tomatoman
  • Registratie: November 2000
  • Laatst online: 22:26

Tomatoman

Fulltime prutser

Even controleren of we elkaar goed begrijpen. Laat ik twee literair hoogstaande teksten nemen.
La la la la, lepel
La la la la, lampen
La la la la, lelijk
La la la la, lijm aan mijn vingers
La la la la, lachen
O ja...
La la la la, lolliepop
Aaaa, dat bedoel je
La la la la, lieveling
La la la la, Luilekkerland
Probeer je nu [Character Return][Line Feed]La la la la, li (17 bytes) als deelverzameling te vinden?

Dat kan op de volgende manier. Stel je hebt een geheugenblok M1 met lengte Len1 en een geheugenblok M2 met als lengte Len2. Nu probeer je het grootste aantal aaneengesloten bytes te vinden dat in beide geheugenblokken voorkomt. Delphi heeft zoekfuncties voor strings, dus gebruiken we die. Dat neemt natuurlijk niet weg dat het onderstaande voorbeeld werkt voor willekeurige geheugenblokken, waar helemaal geen strings in hoeven staan!

Delphi:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
{ Zet drie Memo's en een button op een form. }
{ In Memo1 en Memo2 moet de tekst uit de quotes staan. }
var
  Longest: Pointer;
  LongestLen: Cardinal;

procedure FindIntersection(M1, M2: Pointer; Len1, Len2: Cardinal);
var
  PosM1: PChar;      // huidige positie in M1
  TestStr: string;   // huidige string die gezocht moet worden
  TestLen: Cardinal; // lengte van TestStr
  TestStrPos: PChar; // positie waar huidige string gevonden is
  MoveToNextByte: Boolean;
begin
  Longest := nil;
  LongestLen := 0;
  PosM1 := PChar(M1);
  if (Len1 > 0) and (Len2 > 0) then
  repeat
    TestLen := LongestLen;
    repeat
      MoveToNextByte := False;
      Inc(TestLen);
      TestStr := PosM1;
      SetLength(TestStr, TestLen);
      TestStrPos := SearchBuf(PChar(M2), Len2, 0, 0, TestStr,
        [soDown, soMatchCase]);
      if TestStrPos = nil then
        MoveToNextByte := True
      else
      begin
        LongestLen := TestLen;
        Longest := TestStrPos;
      end;
    until MoveToNextByte;
    { PosM1 een byte opschuiven }
    Cardinal(PosM1) := Cardinal(PosM1) + 1;
  { doorgaan tot en met PosM1 gelijk is aan de laatste byte in M1 }
  until Cardinal(PosM1) = Cardinal(M1) + Len1;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  Fmt = 'Positie: %p,    Lengte: %d,    Tekst: %s';
var
  Txt: string;
begin
  FindIntersection(PChar(Memo1.Text), PChar(Memo2.Text),
    Length(Memo1.Text), Length(Memo2.Text));
  Txt := PChar(Longest);
  SetLength(Txt, LongestLen);
  Memo3.Text := Format(Fmt, [Longest, LongestLen, Txt]);
end;



Literaire bron: 'k Wist niet dat je kwaad werd!!! en andere hits uit Sesamstraat

Een goede grap mag vrienden kosten.


  • jvdmeer
  • Registratie: April 2000
  • Laatst online: 22:57
tomatoman schreef op 22 maart 2003 @ 14:58:
Bedankt voor je uitgebreide uitleg en code. Je hebt me qua procedure op gang geholpen. Ik ga de function maar zelf schrijven, omdat er in mijn data #0 kan voorkomen en dat lijkt in jouw code niet goed te gaan.
Pagina: 1