Forum: Ders Arası RSS
Değişkenlerin bellekteki durumları
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Değişkenlerin bellekteki durumları
D.ershane'de belleği incelemek için küçük işlevler vardı. Onları hızlıca geliştirdim:

import std.stdio;
import std.traits;
import std.ascii;
import std.range;
import std.string;
 
class GirintiliYazıcı
{
    enum birim = "    ";
    string girinti;
 
    this(size_t düzey)
    {
        this.girinti = std.array.replicate(birim, düzey);
    }
 
    void girintiArttır(size_t adım = 1)
    {
        girinti ~= std.array.replicate(birim, adım);
    }
 
    void girintiAzalt(size_t adım = 1)
    {
        girinti = girinti[0 .. $ - adım * birim.length];
    }
 
    void yaz(T...)(T bilgi)
    {
        writeln(girinti, bilgi);
    }
}
 
string[] düzenliBaytSatırları(const ubyte[] bellek)
{
    string[] satırlar;
    string sonSatır;
    string sonSatırAscii;
 
    foreach (i, bayt; bellek) {
        sonSatır ~= format("%02x", bayt);
        sonSatırAscii ~= isPrintable(bayt) ? bayt : '.';
 
        immutable sonrakiİndeks = i + 1;
        if (!(sonrakiİndeks % 16)) {
            satırlar ~= sonSatır ~ "  " ~ stripRight(sonSatırAscii);
            sonSatır = sonSatır.init;
            sonSatırAscii = sonSatırAscii.init;
 
        } else if (!(sonrakiİndeks % 8)) {
            sonSatır ~= "  ";
            sonSatırAscii ~= ' ';
 
        } else {
            sonSatır ~= ' ';
        }
    }
 
    if (!sonSatır.empty) {
        satırlar ~= sonSatır ~ "  " ~ stripRight(sonSatırAscii);
    }
 
    return satırlar;
}
 
/**
 * Belirtilen adresteki belirtilen sayıdaki baytı gösterir
 */
void belleğiGöster(const ubyte * bellek, size_t adet, GirintiliYazıcı yazıcı)
{
    yazıcı.girintiArttır(2);
    scope (exit) yazıcı.girintiAzalt(2);
 
    foreach (satır; düzenliBaytSatırları(bellek[0..adet])) {
        yazıcı.yaz(satır);
    }
}
 
/**
 * Belirtilen değişkenin bellekteki baytlarını gösterir.
 *
 * Dizi türlerinde ayrıca dizi elemanlarını oluşturan baytları da gösterir.
 */
void baytlarınıGöster_girintili(T)(ref T değişken, GirintiliYazıcı yazıcı)
{
    void yaz(T...)(T bilgi)
    {
        yazıcı.yaz(bilgi);
    }
 
    const ubyte * baş = cast(ubyte*)&değişken;
 
    yaz(format("tür: %s", T.stringof));
    yaz(format("değer: %s", değişken));
    yaz(format(".sizeof: %s", T.sizeof));
    yaz(format("adres: %s", baş));
 
    belleğiGöster(baş, T.sizeof, yazıcı);
 
    static if (isArray!T) {
        yaz(format(".length: %s", değişken.length));
        yaz(format(".ptr: %s", değişken.ptr));
 
        size_t uzunluk = değişken.length * ElementEncodingType!T.sizeof;
        belleğiGöster(cast(ubyte*)değişken.ptr, uzunluk, yazıcı);
 
        /* Dizgilerin karakterlerini tek tek eleman olarak göstermeye gerek
         * olmadığını düşünüyoruz. */
        if (!isSomeString!T) {
            yaz("elemanlar:");
            foreach (i, ref eleman; değişken) {
                yazıcı.girintiArttır();
                scope (exit) yazıcı.girintiAzalt();
 
                writeln();
                yaz(format("indeks: %s", i));
 
                baytlarınıGöster_girintili(eleman, yazıcı);
            }
        }
    }
}
 
void baytlarınıGöster(T)(ref T değişken)
{
    writeln();
    baytlarınıGöster_girintili(değişken, new GirintiliYazıcı(0));
}
 
void main()
{
    int[3][2] statikDizi = [ [ 1, 2, 3 ], [ 4, 5, 6 ] ];
    baytlarınıGöster(statikDizi);
 
    auto dizi = [ [ 1, 2, 3 ], [ 4, 5, 6 ] ];
    baytlarınıGöster(dizi);
 
    int i = 99;
    baytlarınıGöster(i);
 
    string s = "merhaba dunya";
    baytlarınıGöster(s);
}

Değişkenlerin bellekte durumlarını incelemek için yararlı olabilir. Çıktısının son satırları şöyle:

tür: int
değer: 99
.sizeof: 4
adres: 7FFF62D4EB98
        63 00 00 00   c...

tür: string
değer: merhaba dunya
.sizeof: 16
adres: 7FFF62D4EBA0
        0d 00 00 00 00 00 00 00  d0 15 48 00 00 00 00 00  ........ ..H.....
.length: 13
.ptr: 004815D0
        6d 65 72 68 61 62 61 20  64 75 6e 79 61   merhaba  dunya
make: Leaving directory `/home/acehreli/deneme/d'


Ali
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hocam eline sağlık...

Ancak belirtmeliyim, dizilerde çok pratik görünmüyor. Yan yana olabilseydi harika olurdu. Örneğin şöyle:
indeks: 0
    tür: int[3u]
    değer: [1,2,3]
    .sizeof: 12
    adres: BFDE8F18
            01 00 00 00 02 00 00 00  03 00 00 00   ........ ....
    .length: 3
    .ptr: BFDE8F18
            01 00 00 00 02 00 00 00  03 00 00 00   ........ ....
    elemanlar:

        indeks: 0
        tür:     int                int                int
        değer:   1                  2                  3
        .sizeof: 4                  4                  4
        adres:   BFDE8F18           BFDE8F1C           BFDE8F20
                 01 00 00 00  ....  02 00 00 00  ....  03 00 00 00   ....
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Hatta her elemanın bilgisi de tekrarlanmamalı. Dediğim gibi, hızlıca yazdığım ve varolan işlevi özyinelemeli çağırdığım için öyle oldu. Gelişmeleri bekliyoruz. ;)

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-18, 07:40:59 (UTC -08:00)