String'ler ve Pointer'lar...

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
memiky
Üye
Mesajlar: 116
Kayıt: 17 Kas 2004 01:52
İletişim:

String'ler ve Pointer'lar...

Mesaj gönderen memiky »

Arkadaşlar bildiğiniz gibi String değişkenler Char tipindeki dinamik dizi değişkenler gibi işlev görmektedir. Pointer değişkenler üzerine çalışırken şeytanın avukatlığına yapma niyetine ve aşağıda verdiğim basit kodu hazırladım.

Var
Str : String;
Ptr : ^Integer;
begin
Str := 'ATA';
Ptr := @Str[1];
Edit1.Text := IntToStr(Integer(Ptr));
Edit4.Text := Char(Ptr^);
Ptr := @Str[2];
Edit2.Text := IntToStr(Integer(Ptr));
Edit5.Text := Char(Ptr^);
Ptr := @Str[3];
Edit3.Text := IntToStr(Integer(Ptr));
Edit6.Text := Char(Ptr^);
end;

Bu kodda String değişkenin uzunluğu belli. Ayrıca Length() fonksiyonu ile bu dizi değişkenin veya String bilginin uzunluğu öğrenilebilmektedir. Benim asıl üzerinde durup merak ettiğim konu ise Length() fonksiyonunu kullanmadan String bilginin uzunluğunu veya dizi değişkenin eleman sayısını öğrenmek. Umarım merakımı saçma bulmazsınız.
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Kod: Tümünü seç

type
  PStrRec = ^StrRec;
  StrRec = packed record
    refCnt: Longint;
    length: Longint;
  end;

function PascalLength(const S: string): Integer;
begin
 Result := 0;
  if Pointer(s) <> nil then
    Result := PStrRec(Integer(s) - sizeof(StrRec)).length;
end;
olabilir mi?
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

Assembler olarak:

Kod: Tümünü seç

type
  PStrRec = ^StrRec;
  StrRec = packed record
    refCnt: Longint;
    length: Longint;
  end; 

const
  skew = SizeOf(StrRec);

function AsmLength(const S: string): Integer; 
asm
        { ->    EAX str }

        TEST    EAX,EAX
        JE      @@done
        MOV     EAX,[EAX-skew].StrRec.length;
@@done:
end;
Delphi System unitindeki _LStrLen function'ından aldım bütün bunları. :twisted:
memiky
Üye
Mesajlar: 116
Kayıt: 17 Kas 2004 01:52
İletişim:

Mesaj gönderen memiky »

coderlord'a teşekkürler.. Verdiğiniz kod çalışıyor ve işe yarıyor.. Herkese saygılar
fduman
Moderator
Mesajlar: 2749
Kayıt: 17 Ara 2004 12:02
Konum: Ankara

Mesaj gönderen fduman »

coderlord yazdı:

Kod: Tümünü seç

    Result := PStrRec(Integer(s) - sizeof(StrRec)).length;
Benim bu koddan anladığım şudur ki:
Bir long string veya dinamik dizinin uzunluğu:

(string veya dizinin bellekteki adresi) - (StrRec uzunluğu + StrRec.refCnt'ın uzunluğu)
'tan 32 bitlik bir veri olarak elde edilebiliyor. Yani String'in bellek adresinin hemen başında böyle bir (StrRec) kayıt tutuluyor.

Bu refcnt "Reference Counter" olmalı. Delphi bu değeri string veya dinamik dizi değerlerinin işi bittikten sonra, bellekten otomatik temizlemede kullanıyor. Bu sayede bizim manuel olarak string'i deallocate yapmamıza gerek olmuyor.

Diye yorumluyorum. Siz ne dersiniz?
En son fduman tarafından 28 Oca 2005 02:22 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
memiky
Üye
Mesajlar: 116
Kayıt: 17 Kas 2004 01:52
İletişim:

Mesaj gönderen memiky »

Yazdıklarınıza katılıyorum. Ama bu konuda yeterince araştırma yapmadığımı belirtmek isterim..

Delphi'nin gücü burada; hiç kafa yormadan ve sorun yaşamadan String bilgileri birleştir, böl vs. Ama merak edersen geri planda olanları görme ve müdahele etme imkanını veriyor...
Cevapla