Forum: Ders Arası RSS
BUG: Neden immutable olmayan dizge/dizi değiştirilemez?
Avatar
Salih Dinçer #1
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: BUG: Neden immutable olmayan dizge/dizi değiştirilemez?
Merhaba,

Aslında iki güzel örnek hazırlamıştım ama hatanın odağını buldukça örnekleri küçülttüm. Özü aşağıdaki gibi ve gizlenen satır açıldığında hata vermemesi gerekiyor! Verdiği hata Parçalama arızası (Segmentation fault) ve bu, beni darmadağın etti...:)
import std.stdio;
 
int main() {
  char[] pir = [ 'P', 'i', 'r' ];
  char[] deneme = cast(char[])"C Dili";
  
  pir.writeln(", ", typeid(pir));
  deneme.writeln(", ", typeid(deneme));
  
  //deneme[0] = 'D';/* <-- bu satır "Segmentation fault" hatası vermekte! 
  pir[0] = 'D';
  pir[2] = 'l';//*/
  pir.writeln();
}/* Çıktısı:
  * Pir, char[]
  * C Dili, char[]
  * Dil
  */
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
Bu mesaj Salih Dinçer tarafından değiştirildi; zaman: 2012-08-18, 04:25.
Değişiklik nedeni: Ekran çıktısını ekledim...
Avatar
Salih Dinçer #2
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hadi içimde kalmasın, sondan birinci örneği paylaşayım ve çözümü önereyim:
import std.stdio;
 
int main() {
  char[] deneme = cast(char[])"D Dili";//*/
  int[] tekler = [ 1, 3, 5, 7, 9, 11 ];
  
  deneme.writeln; // D dili
  tekler.writeln; // [1, 3, 5, 7, 9, 11]
  
  writeln(); //*/
  
  char[] birDilim;
  
  birDilim =  deneme[2 .. $ - 1];
  birDilim.writeln; // Dil
  //birebirAktar!char(birDilim, cast(char[])"Pir");
  deneme.writeln; //* D Piri <-- yazmıyor, çünkü üst satır çalışmıyor...:)             */
  
  writeln(); //*/
  
  int[] intDilim; // başka bir dilim...:)
  
  intDilim = tekler[2 .. $ - 1];
  intDilim.writeln;
  birebirAktar!int(intDilim, [4, 5, 6]);
  tekler.writeln; //* [1, 3, 4, 5, 6, 11]       int'de çalışıyor!             */
}
 
void birebirAktar(T)(ref T[] hedef, T[] aktar) {
    size_t SINIR = hedef.length <= aktar.length ?
                   hedef.length-1 : // hedef büyükse =>
                   aktar.length-1;
    while(SINIR+1) {
        hedef[SINIR] = aktar[SINIR];
        SINIR--;
    }
}
Sorun, sanırım tür dönüşümü olarak olarak kullandığımız cast()'de. Çünkü böyle bir şey yapmadığımızda örnek bir güzel çalışıyor. Bunu görmek için deneme dizisinin eşitliğinden sonra şu satırı/değerleri yapıştırın:
[ 'D', ' ', 'D', 'i', 'l', 'i' ];/*** gizli olan satırı açmayı unutmayın *** 
Bu durumda çıktısı şu şekilde olmalı:

D Dili
[1, 3, 5, 7, 9, 11]

Dil
D Piri

[5, 7, 9]
[1, 3, 4, 5, 6, 11]


Kafayı yemek üzereydim ve Ali hocanın derslerine sarıldım. Kendi kendime dedim, herhalde dilim olayını henüz tam öğrenememiş olmalıyım ki bir şeyi ihmal ediyorum. Dikkat ederseniz örnekte tekler diye bir dizi var ve bunu oradan aldım. Örneğin ikinci bölümünde tek sayılar kümesi tam istediğim gibi bozuluyor ama "D Dili" bir türlü "D Piri" olmuyor...:)

İlginçtir, birebirAktar() ismindeki işlevin ikinci parametresine yine cast() ile veri aktarmaktayım. Yani cast() doğru çalışıyor ama bu veri sanki immutable olan string'den nem kapmış olacak ki değiştirilemiyor. Eee, atalarımız ne demiş? Huylu huyundan vazgeçmez imiş...:)

Dip Not: std.conv.to!... şablonunu denemedim. Belki o daha doğru çalışıyor olabilir...
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ı
"C Dili" gibi hazır dizgi sabitlerinin türünü biliyorsun; karakterleri değiştirilemez. Derleyici onu değiştirilmesinin mümkün olmadığı bir bellek bölgesinde kurabilir. (Linux işletim sistemi bu konuda yardımcıdır.)

Derleyiciye "bana güven, o (immutable)char[] sandığın yerde aslında bir (char)[] var" diyorsun. (cast yoluyla.) Derleyici de bir sistem dili olduğu için "tabii ki, buyrun" diyor.

İşletim sistemi de o bölgeye yazmaya kalkıldığında patlıyor.

Ali
Avatar
Salih Dinçer #4
Üye Ock 2012 tarihinden beri · 1912 mesaj · Konum: İstanbul
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Hmm, ben cast()'in bir nevi dönüştürme içişlevi olduğunu zannediyordum. O yüzden daha çok fikir edinebilmek için bunu yabancı foruma sordum....

Orada bunun bir bug olmadığını söylediler ve Ali hocamın yazdığı gibi kıymetli bilgiler eklediler. Meğer ilacı .dup imiş de cast()'e bile gerek yokmuş...

Dip Not: typeid() içişlevi ile değerlere karşılaştırmış olmak beni aldattı ve meğer farklı şeylermiş...:)
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)
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-22, 05:08:05 (UTC -08:00)