Go ile Pointerlar
Belleği dinamik bir şekilde yönetmemizi sağlayan pointeraları Go programlama dili ile ele alıyoruz.
C, C++, Rust gibi sistem programlama dillerinde yaygın olarak kullanılan ve programcının belleği dinamik olarak yönetmesini sağlayan pointerları Go dilini kullanarak birlikte inceleyelim.
Program yazarken bir değişken tanımladığımızda o değişkenin veri türüne göre bellekte belli büyüklükte bir alan tahsis edilir. Örneğin Go dili ile 64 bit mimariye sahip bir geliştirme ortamında int (tamsayı) türünde bir değişken tanımlayalım, Bu değişkenin tutacağı değer için bellekte 64 bit yani 8 byte’lık bir alan rezerve edilir. Sonrasında bu değişkene bir değer atama işlemi gerçekleştirdiğimizde ise rezerve edilen bölgeye değişkenin değeri yerleştirilir. Peki biz bu değerin bellekteki konumunu öğrenebilir miyiz veya bellekteki konumunu değiştirebilir miyiz? Cevap tabiki de evet. Bu noktada pointerlar devreye giriyor ve belleği manipüle etmemize olanak tanıyor. Peki öyleyse pointer kavramını tanımlayalım ve nasıl kullanıldığını inceleyelim.
Pointerlar, bellekteki bir verinin bulunduğu adresi tutan veri yapılarıdır. Bir değişkenin adresine değişkenin önüne & (ampersand) operatörü konularak erişilir.
Şimdi bir değişken tanımlayıp değer atamasını gerçekleştirelim ve bellekte bulunduğu adresi gözlemleyelim.
Yukarıdaki kodda ilk olarak int veri türünde, değeri 12 olan, number isminde bir değişken oluşturuyoruz. Sonrasında number değişkeninin önüne & operatörünü yerleştirerek Println fonksiyonu ile ekrana bastırıyoruz. Sonuç olarak “0xc00000a0a8” bu veya buna benzer bir adres çıktısını gözlemleyebiliyoruz. Programı farklı bir zamanda çalıştırdığımızda number değişkeninin bulunduğu adresi farklı bir adres olarak görebiliriz. Bunun nedeni program tekrar çalıştırıldığı anda bellekteki o adresin farklı bir program tarafından kullanılıyor olması veya önceki durumdan belleğin daha az dolu olması ve öncelikle o boş alanlara yerleşmesinden kaynaklanıyor olabilir. Neticede farklı sonuçlar görmemizin bir hata olmadığını bilmemiz gerekiyor.
Bir değişkenin adresine bulunduğu adrese erişmeyi başardık. Peki bir adresteki değeri görüntülemek istediğimizde ne yapmamız gerekiyor? Bu durumda adres tutan değişkenin (pointer) önüne * (asteriks) operatörünü koyduğumuzda o adreste tutulan veriyi elde edebiliyoruz.
Yukarıdaki kodda ilk kodda olduğu gibi number isminde 12 değerini tutan bir değişken oluşturuyoruz. Sonrasında number değişkeninin adresini tutacak “numberP” isimli bir pointer (işaretçi) değişken tanımlıyoruz (Pointer yani adres tutan bir değişken tanımlarken normal değişken tanımlamadan farklı olarak veri türünden önce * operatörünün konulması gerekiyor) ve number’ın adresini numberP değişkenine atıyoruz. Böylelikle number’ın adresini tutan bir pointer değişkenine sahip olmuş oluyoruz. “numberP”nin tuttuğu adresteki değeri görüntülemek istediğimizde ise numberP’nin önüne * operatörünü koyuyoruz ve değeri elde ediyoruz. Yukarıdaki kod için 12 sonucunu ekranda görüntülüyor olacağız.
Yukarıda yaptıklarımız kafanızda çok iyi canlanmamış veya eksik parçalar kalmış olabilir. Bu durumu düzeltmek adına yaptığımız işlemleri modelleyelim.
İlk olarak “number” isminde değeri 12 olan bir değişken oluşturmuştuk.
Bu değişken aşağıdaki gibi bellekte boş bir alana yerleşecektir.
Sonrasında ise numberP isminde bir pointer değişkeni oluşturup number’ın adresini bu pointer değişkenine atama işlemini gerçekleştirmiştik. Sonuç olarak bu durumu aşağıdaki gibi modelleyebiliriz.