Yorumları: 4.224
Konuları: 379
Kayıt Tarihi: 07-07-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 16.975 Üstad
21-09-2016, Saat: 11:44
(Son Düzenleme: 21-09-2016, Saat: 12:12, Düzenleyen: TescilsizUzman.)
Merhaba,
Büyük projelerde belki yüzlerce hatta binlerce sabit kullanılır. Bu durumda bellek yönetimi son derece önem kazanmaktadır. Bir çoğumuz bu tip konulara dikkat etmesek de bilmenin faydalı olacağını düşünerek bir soru ile beyin fırtınası yaparak, bu kapsamda doğru yolu bulalım diyorum.
Örneğin 3 karakterim var ve bunu sabit olarak tanımlamak istiyorum.
type
TKullanıcıTanımlıBirDeğerDaha = (a, b, c);
TKullanıcıTanımlıBirDeğerDahaTumu = set of TKullanıcıTanımlıBirDeğerDaha;
TBirKüme = 'a' .. 'b';
TBirKümeTüm = set of TBirKüme;
resourcestring
resDeğer = 'abc';
const
cnsDeğer1 = 'abc';
cnsDeğer2: ShortString = 'abc';
cnsDeğer3: String = 'abc';
cnsDeğer4: AnsiString = 'abc';
cnsDeğer5: WideString = 'abc';
cnsDeğer6: TKullanıcıTanımlıBirDeğerDahaTumu = [a, b, c];
cnsDeğer7: TBirKümeTüm = ['a', 'b', 'c'];
cnsDeğer8: array [0 .. 2] of Char = ('a', 'b', 'c');
cnsDeğer9: array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
cnsDeğer10: array [0 .. 2] of WideChar = ('a', 'b', 'c');
- Hangi tanımlama hafızada ne kadar yer kaplar?
- Delphi/Object Pascal ile bu tanımlamayı daha kaç farklı şekilde yapabilirim?
- Hangisi daha avantajlı ve hızlı olur?
- En az işleme tabi tutarak kullanabileceğim tip hangisi?
Sabit veya değişken tanımlamaların rastgele yapılmaması ve bilinçli yapılmasının ne derece önemli olduğunu belirtir bir yazı paylaşıyorum.
Alıntı:4 Haziran 1996 — Ariane 5 Flight 501: Ariane 4 roketinin çalışma kodu Ariane 5’te yeniden kullanılmıştı. Fakat Ariane 5’in daha hızlı olan motoru, roketin uçuş bilgisayarındaki bir aritmetik işlemde bir hatanın ortaya çıkmasına yol açıyordu. Hata, bilgisayar ifadeleriyle, 64 bitlik ondalıklı sayıyı 16 bitlik işaretli tam sayıya dönüştüren kodda idi. Daha hızlı motor 64 bitlik sayıların Ariane 5’te, Ariane 4 de olduğundan daha büyük olmasına yol açıyor ve böylece sayısal taşma durumu yaratıyor, o da uçuş bilgisayarının çökmesini getiriyordu. Flight 501’in destek bilgisayarı çöktü, 0.05 saniye sonra da ana bilgisayar çöktü. Çöken bilgisayarlar sonucu, roketin ana işlemcisi motorlara aşırı güç yüklenmesine yol açtı ve roket, fırlatıldıktan 40 saniye sonra, parçalandı.
Bu ve buna benzer daha bir çok örnek var. : Bakın
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
21-09-2016, Saat: 12:19
(Son Düzenleme: 21-09-2016, Saat: 12:30, Düzenleyen: Tuğrul HELVACI.)
İşte bu ve buna benzer nedenlerden ötürü Low Level programlama olmazsa olmazlardandır.
Ayrıca aşağıdaki örneği inceleyebilirsiniz:
procedure TForm1.Button1Click(Sender: TObject);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
var
Arr : array of Byte;
begin
SetLength(Arr, 1024);
ShowMessage('S1 Size:' + SizeOf(S1).ToString());
ShowMessage('S2 Size:' + SizeOf(S2).ToString());
ShowMessage('A1 Size:' + SizeOf(A1).ToString());
ShowMessage('C1 Size:' + SizeOf(C1).ToString());
ShowMessage('C2 Size:' + SizeOf(C2).ToString());
ShowMessage('C3 Size:' + SizeOf(C3).ToString());
ShowMessage('Arr Size:' + SizeOf(Arr).ToString());
Arr := nil;
end;
String'lerin , dinamik dizilerin birer pointer olduğunu unutmayın
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 858
Konuları: 35
Kayıt Tarihi: 12-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 3.731 Uzman
Selam, burada önemli olan hafızadaki kapladığı alan değilmidir? Tuğrul hocam verdiğiniz örneğe göre size larını görebiliyoruz, hemen hemen aynı hepsi. Ben biraz değiştirip şöyle bişi yaptım ama burda dikkatimi çeken bişi oldu.
procedure TForm1.Button1Click(Sender: TObject);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
S4 = 'Deneme';
var
Arr1 : array of Byte;
S3 : STRING;
Arr2 : array of Byte;
begin
SetLength(Arr1, 1024);
SetLength(Arr2, 1024);
S3:='DenemeDeneme3';
MEMO1.Lines.Add('-----------------------------------');
MEMO1.Lines.Add(
'S1 : Address: ' + IntToStr (Integer (S1)) +
', Length: ' + IntToStr (Length (S1)) +
', References: ' + IntToStr (PInteger (Integer (S1) - 8)^) +
', Size: ' + IntToStr(SizeOf(S1)) +
', Value: ' + S1);
MEMO1.Lines.Add(
'S2 : Address: ' + IntToStr (Integer (S2)) +
', Length: ' + IntToStr (Length (S2)) +
', References: ' + IntToStr (PInteger (Integer (S2) - 8)^) +
', Size: ' + IntToStr(SizeOf(S2)) +
', Value: ' + S2);
MEMO1.Lines.Add(
'S3 : Address: ' + IntToStr (Integer (S3)) +
', Length: ' + IntToStr (Length (S3)) +
', References: ' + IntToStr (PInteger (Integer (S3) - 8)^) +
', Size: ' + IntToStr(SizeOf(S3)) +
', Value: ' + S3);
MEMO1.Lines.Add(
'S4 : Address: ' + IntToStr (Integer (S4)) +
', Length: ' + IntToStr (Length (S4)) +
', References: ' + IntToStr (PInteger (Integer (S4) - 8)^) +
', Size: ' + IntToStr(SizeOf(S4)) +
', Value: ' + S4);
MEMO1.Lines.Add(
'A1 : Address: ' + IntToStr (Integer (A1)) +
', Length: ' + IntToStr (Length (A1)) +
', References: ' + IntToStr (PInteger (Integer (A1) - 8)^) +
', Size: ' + IntToStr(SizeOf(A1)) +
', Value: ' + A1);
MEMO1.Lines.Add(
'C1 : Address: ' + IntToStr(Integer(@C1)) +
', Length: ' + IntToStr (Length (C1)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(C1)) +
', Value: ' + C1);
MEMO1.Lines.Add(
'C2 : Address: ' + IntToStr(Integer(@C2)) +
', Length: ' + IntToStr (Length (C2)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(C2)) +
', Value: ' + C2);
MEMO1.Lines.Add(
'C3 : Address: ' + IntToStr(Integer(@C3)) +
', Length: ' + IntToStr (Length (C3)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(C3)) +
', Value: ' + C3);
MEMO1.Lines.Add(
'Arr1 : Address: ' + IntToStr(Integer(@Arr1)) +
', Length: ' + IntToStr (Length (Arr1)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(Arr1)) +
', Value: ' + INTTOSTR(Arr1[0]));
MEMO1.Lines.Add(
'Arr2 : Address: ' + IntToStr(Integer(@Arr2)) +
', Length: ' + IntToStr (Length (Arr2)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(Arr2)) +
', Value: ' + INTTOSTR(Arr2[0]));
Arr1 := nil;
Arr2 := nil;
end;
kodun sonucu (tanımlamalar ile birlikte yazdım);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
S4 = 'Deneme';
var
Arr1 : array of Byte;
S3 : STRING;
Arr2 : array of Byte;
begin
SetLength(Arr1, 1024);
SetLength(Arr2, 1024);
S3:='DenemeDeneme3';
-----------------------------------
S1 : Address: 4520904, Length: 6, References: -1, Size: 4, Value: Deneme
S2 : Address: 9779496, Length: 6, References: 1, Size: 4, Value: Deneme ****************
S3 : Address: 4522824, Length: 13, References: -1, Size: 4, Value: DenemeDeneme3
S4 : Address: 9780912, Length: 6, References: 1, Size: 4, Value: Deneme ****************
A1 : Address: 4520920, Length: 6, References: -1, Size: 4, Value: Deneme
C1 : Address: 4529580, Length: 3, References: . , Size: 3, Value: abc
C2 : Address: 4529584, Length: 3, References: . , Size: 3, Value: abc
C3 : Address: 4529588, Length: 3, References: . , Size: 6, Value: abc
Arr1 : Address: 1308200, Length: 1024, References: . , Size: 4, Value: 0 ********************
Arr2 : Address: 1308192, Length: 1024, References: . , Size: 4, Value: 0 *********************
burda dikkatimi çeken şu oldu, string ansistring char vs. hafızanın belli bir bölgesinden tahsis edildi, arrayler farklı bir bölgeden, resource lar farklı bir bölgeden, yada banamı öyle denk geldi, birkaç deneme yaptım hep benzer sonuçlar aldım, bunun bir anlamı varmıdır? ( * işareti ile işaretlediğim adresler )
Yorumları: 4.224
Konuları: 379
Kayıt Tarihi: 07-07-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 16.975 Üstad
(21-09-2016, Saat: 12:19)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: İşte bu ve buna benzer nedenlerden ötürü Low Level programlama olmazsa olmazlardandır.
Ayrıca aşağıdaki örneği inceleyebilirsiniz:
procedure TForm1.Button1Click(Sender: TObject);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
var
Arr : array of Byte;
begin
SetLength(Arr, 1024);
ShowMessage('S1 Size:' + SizeOf(S1).ToString());
ShowMessage('S2 Size:' + SizeOf(S2).ToString());
ShowMessage('A1 Size:' + SizeOf(A1).ToString());
ShowMessage('C1 Size:' + SizeOf(C1).ToString());
ShowMessage('C2 Size:' + SizeOf(C2).ToString());
ShowMessage('C3 Size:' + SizeOf(C3).ToString());
ShowMessage('Arr Size:' + SizeOf(Arr).ToString());
Arr := nil;
end;
String'lerin , dinamik dizilerin birer pointer olduğunu unutmayın
Char ve WideChar 2 Byte iken neden AnsiChar 1 Byte?
Yorumları: 1.460
Konuları: 80
Kayıt Tarihi: 05-08-2016
Aktif Kullandığınız Delphi Sürümü:
Rep Puanı: 11.868 Üstad
21-09-2016, Saat: 15:17
(Son Düzenleme: 21-09-2016, Saat: 15:21, Düzenleyen: Tuğrul HELVACI.)
(21-09-2016, Saat: 15:11)Fesih ARSLAN Adlı Kullanıcıdan Alıntı: (21-09-2016, Saat: 12:19)Tuğrul HELVACI Adlı Kullanıcıdan Alıntı: İşte bu ve buna benzer nedenlerden ötürü Low Level programlama olmazsa olmazlardandır.
Ayrıca aşağıdaki örneği inceleyebilirsiniz:
procedure TForm1.Button1Click(Sender: TObject);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
var
Arr : array of Byte;
begin
SetLength(Arr, 1024);
ShowMessage('S1 Size:' + SizeOf(S1).ToString());
ShowMessage('S2 Size:' + SizeOf(S2).ToString());
ShowMessage('A1 Size:' + SizeOf(A1).ToString());
ShowMessage('C1 Size:' + SizeOf(C1).ToString());
ShowMessage('C2 Size:' + SizeOf(C2).ToString());
ShowMessage('C3 Size:' + SizeOf(C3).ToString());
ShowMessage('Arr Size:' + SizeOf(Arr).ToString());
Arr := nil;
end;
String'lerin , dinamik dizilerin birer pointer olduğunu unutmayın
Char ve WideChar 2 Byte iken neden AnsiChar 1 Byte?
Üstad, Delphi'nin 2009 sürümünden sonra, yani Delphi Unicode desteğinden sonra; Char = WideChar oldu, yani Char artık 2 byte. Dolayısı ile bir byte'lık eski karakterler AnsiChar ve bir byte'lık karakter dizileri de AnsiString üzerinden yürüyor.
(21-09-2016, Saat: 14:47)esistem Adlı Kullanıcıdan Alıntı: Selam, burada önemli olan hafızadaki kapladığı alan değilmidir? Tuğrul hocam verdiğiniz örneğe göre size larını görebiliyoruz, hemen hemen aynı hepsi. Ben biraz değiştirip şöyle bişi yaptım ama burda dikkatimi çeken bişi oldu.
procedure TForm1.Button1Click(Sender: TObject);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
S4 = 'Deneme';
var
Arr1 : array of Byte;
S3 : STRING;
Arr2 : array of Byte;
begin
SetLength(Arr1, 1024);
SetLength(Arr2, 1024);
S3:='DenemeDeneme3';
MEMO1.Lines.Add('-----------------------------------');
MEMO1.Lines.Add(
'S1 : Address: ' + IntToStr (Integer (S1)) +
', Length: ' + IntToStr (Length (S1)) +
', References: ' + IntToStr (PInteger (Integer (S1) - 8)^) +
', Size: ' + IntToStr(SizeOf(S1)) +
', Value: ' + S1);
MEMO1.Lines.Add(
'S2 : Address: ' + IntToStr (Integer (S2)) +
', Length: ' + IntToStr (Length (S2)) +
', References: ' + IntToStr (PInteger (Integer (S2) - 8)^) +
', Size: ' + IntToStr(SizeOf(S2)) +
', Value: ' + S2);
MEMO1.Lines.Add(
'S3 : Address: ' + IntToStr (Integer (S3)) +
', Length: ' + IntToStr (Length (S3)) +
', References: ' + IntToStr (PInteger (Integer (S3) - 8)^) +
', Size: ' + IntToStr(SizeOf(S3)) +
', Value: ' + S3);
MEMO1.Lines.Add(
'S4 : Address: ' + IntToStr (Integer (S4)) +
', Length: ' + IntToStr (Length (S4)) +
', References: ' + IntToStr (PInteger (Integer (S4) - 8)^) +
', Size: ' + IntToStr(SizeOf(S4)) +
', Value: ' + S4);
MEMO1.Lines.Add(
'A1 : Address: ' + IntToStr (Integer (A1)) +
', Length: ' + IntToStr (Length (A1)) +
', References: ' + IntToStr (PInteger (Integer (A1) - 8)^) +
', Size: ' + IntToStr(SizeOf(A1)) +
', Value: ' + A1);
MEMO1.Lines.Add(
'C1 : Address: ' + IntToStr(Integer(@C1)) +
', Length: ' + IntToStr (Length (C1)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(C1)) +
', Value: ' + C1);
MEMO1.Lines.Add(
'C2 : Address: ' + IntToStr(Integer(@C2)) +
', Length: ' + IntToStr (Length (C2)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(C2)) +
', Value: ' + C2);
MEMO1.Lines.Add(
'C3 : Address: ' + IntToStr(Integer(@C3)) +
', Length: ' + IntToStr (Length (C3)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(C3)) +
', Value: ' + C3);
MEMO1.Lines.Add(
'Arr1 : Address: ' + IntToStr(Integer(@Arr1)) +
', Length: ' + IntToStr (Length (Arr1)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(Arr1)) +
', Value: ' + INTTOSTR(Arr1[0]));
MEMO1.Lines.Add(
'Arr2 : Address: ' + IntToStr(Integer(@Arr2)) +
', Length: ' + IntToStr (Length (Arr2)) +
', References: . ' +// IntToStr (PInteger (Integer (C1) - 8)^) +
', Size: ' + IntToStr(SizeOf(Arr2)) +
', Value: ' + INTTOSTR(Arr2[0]));
Arr1 := nil;
Arr2 := nil;
end;
kodun sonucu (tanımlamalar ile birlikte yazdım);
const
S1 : String = 'Deneme';
A1 : AnsiString = 'Deneme';
C1 : array [0 .. 2] of Char = ('a', 'b', 'c');
C2 : array [0 .. 2] of AnsiChar = ('a', 'b', 'c');
C3 : array [0 .. 2] of WideChar = ('a', 'b', 'c');
resourcestring
S2 = 'Deneme';
S4 = 'Deneme';
var
Arr1 : array of Byte;
S3 : STRING;
Arr2 : array of Byte;
begin
SetLength(Arr1, 1024);
SetLength(Arr2, 1024);
S3:='DenemeDeneme3';
-----------------------------------
S1 : Address: 4520904, Length: 6, References: -1, Size: 4, Value: Deneme
S2 : Address: 9779496, Length: 6, References: 1, Size: 4, Value: Deneme ****************
S3 : Address: 4522824, Length: 13, References: -1, Size: 4, Value: DenemeDeneme3
S4 : Address: 9780912, Length: 6, References: 1, Size: 4, Value: Deneme ****************
A1 : Address: 4520920, Length: 6, References: -1, Size: 4, Value: Deneme
C1 : Address: 4529580, Length: 3, References: . , Size: 3, Value: abc
C2 : Address: 4529584, Length: 3, References: . , Size: 3, Value: abc
C3 : Address: 4529588, Length: 3, References: . , Size: 6, Value: abc
Arr1 : Address: 1308200, Length: 1024, References: . , Size: 4, Value: 0 ********************
Arr2 : Address: 1308192, Length: 1024, References: . , Size: 4, Value: 0 *********************
burda dikkatimi çeken şu oldu, string ansistring char vs. hafızanın belli bir bölgesinden tahsis edildi, arrayler farklı bir bölgeden, resource lar farklı bir bölgeden, yada banamı öyle denk geldi, birkaç deneme yaptım hep benzer sonuçlar aldım, bunun bir anlamı varmıdır? ( * işareti ile işaretlediğim adresler )
Evet vardır üstad. Normalde tanımladığın local değişkenler PE/PE+'ın code section'unda; resource'lar ise şimdi adını anımsayamadığım başka bir section'da yer alıyorlar. Dolayısı ile farklı lokasyondalar. Ayrıca, local değişkenler Stack'da; global değişkenler Heap'de kendilerine yer bulurlar. Tahsisat hafızanın farklı lokasyonları üzerinde yapılır. Tabii burada detaylara tam haiz olabilmek için Delphi'nin Memory Manager'ı & FastMM hususunda da bilgimiz olması gerekir. Yanlış hatırlamıyorsam eğer; GetMem.inc dosyası içinden ilgili işlemleri takip edebilirsiniz; ama epeyce karışık olduğunu hatırlıyorum
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
Yorumları: 96
Konuları: 23
Kayıt Tarihi: 08-01-2017
Rep Puanı: 415 Acemi
Güzel basit açıklayıcı
|