Nesneye Yönelik Programlama BM-104 Nesneye Yönelik Programlama Bahar 2013 (8. Sunu) (Yrd. Doç. Dr. Deniz Dal)
new ve delete Operatörleriyle Dinamik Bellek Yönetimi (Dynamic Memory Management) Dinamik bellek yönetimi programcıya, bellekten dinamik olarak yer ayırmak (allocate) ve kullandıktan sonra ayrılan bu alanı belleğe geri vermek (deallocate) için yardımcı olur. (Hem built-in hem de user-defined veri tipleri için.) Bu işlemler new ve delete operatörleri yardımıyla gerçekleştirilir. Bellekte dinamik olarak (boyutu değişken), bir dizi oluşturmak boyutu sabit bir diziyi statik olarak tanımlamaktan birçok kez daha kullanışlıdır.
Dinamik Bellek Yönetimi (devam) new Operatörü Bir sınıfın nesnesi için programın çalışması esnasında (execution time) (derleme anında (compilation time) değil) nesnenin boyutuna uygun bir alanı bellekte rezerve eder. Nesnenin yapıcısını çağırır ve ilk değer atama işlemini gerçekleştirir. Ve son olarak bu nesneye bir pointer atar. Free store ya da heap Dinamik olarak oluşturulacak nesneler için programın çalıştırılması esnasında kullanılan özel bellek alanıdır.
Dinamik Bellek Yönetimi (devam) delete Operatörü Dinamik olarak heap te oluşturulmuş bir nesneyi yok eder. Bu işlemi nesnenin yıkıcısını çağırarak gerçekleştirir ve boşalan alanı heap e iade eder. Belleğin boşaltılan bu alanı başka nesneler tarafından ya da işletim sistemi tarafından yeniden kullanılabilir. Dinamik olarak oluşturulmuş bir bellek alanını kullanımı bittikten sonra serbest bırakmamak “memory leak” denen bir probleme sebep olur. Neden?
Dinamik Değişken ve Nesne Kullanımı Örnek : double *ptr1=new double(3.14159); int *ptr2=new int; *ptr2=16; Zaman *ptr3=new Zaman; Zaman *ptr4=new Zaman(12,45,16); delete ptr1; delete ptr2; delete ptr3; delete ptr4; delete operatörü ptr1 pointerının işaret ettiği dinamik bellek alanını yok eder. Pointer değişkenine bu satırdan sonra da new operatörü ile yeni bir dinamik bellek alanı rezerve edilebilir.
Tek Boyutlu Dinamik Diziler Diziler dinamik olarak çalışma esnasında tanımlanabilirler. Örnek: Dinamik olarak oluşturulacak ve kullanıcıdan klavye yoluyla temin edilecek diziBoyutu kadar elemanı saklayacak integer bir dizinin deklarasyonu: int *diziPtr=new int[diziBoyutu]; delete [] diziPtr; (!! Kare parantezlere dikkat ([])!!) 2 nolu deyim diziPtr adlı dinamik dizinin bellekte tutulduğu alanı istenildiğinde serbest bırakır. Eğer pointer, içinde nesne tutan bir diziyi işaret ediyorsa önce dizinin içindeki nesnelere ait yıkıcılar çağrılır ve daha sonra bellek serbest bırakılır. diziPtr dinamik dizinin ilk elemanını işaret eder. Dizinin ikinci elemanına diziPtr[1] ile veya *(diziPtr+1) ile ulaşılır.
Dinamik Olarak Oluşturulmuş Bir Nesnenin Public Üye Fonksiyonlarına Veya Public Üye Değişkenlerine Ulaşmak İçin 2 Yol Vardır Zaman *ptr=new Zaman; BİRİNCİ YOL: ptr->ZamaniGoster(); İKİNCİ YOL :(*ptr).ZamaniGoster();
Uygulama Kullanıcıdan klavye yoluyla temin edeceğiniz integer bir sayıyı dinamik bir integer dizinin boyutu olarak kullanınız. Bu dizinin içerisini rastgele sayılarla dolduracak Fonksiyon1 adında bir C++ fonksiyonu tanımlayınız. Kendisine parametre olarak aldığı bir tamsayı Leyland Sayısı ise geriye true değilse geriye false döndüren Fonksiyon2 adında bir C++ fonksiyonu tanımlayınız. 1 < y ≤ x iken xy + yx formunda ifade edilebilen sayılar Leyland Sayıları olarak adlandırılırlar. 8, 17, 100 ve 1124 Leyland Sayılarından birkaçıdır. Kendisine parametre olarak aldığı bir alt limit ile bir üst limit arasındaki Leyland Sayılarını alt alta basacak Fonksiyon3 adında bir C++ fonksiyonu tanımlayınız. Dinamik bir integer dizinin içerisindeki Leyland Sayılarını bularak ekrana basacak Fonksiyon4 adında bir C++ fonksiyonu tanımlayınız.
#ifndef LECTURE7_H #define LECTURE7_H class Lecture7 { public: void Fonksiyon1(int*,int); void Fonksiyon3(int,int); void Fonksiyon4(int*,int); private: bool Fonksiyon2(int); }; #endif
#include "Lecture7.h" #include <iostream>//cout ve endl #include <cmath> //pow using namespace std; void Lecture7::Fonksiyon1(int *ptr,int boyut) { cout<<"DINAMIK DIZININ ICERIGI\n"; for(int i=0;i<boyut;i++) ptr[i]=rand(); cout<<*(ptr+i)<<' '; } cout<<endl; bool Lecture7::Fonksiyon2(int sayi) int leylandDegeri; for(int y=2;y<=20;y++) for(int x=y;x<=20;x++) leylandDegeri=(int)pow((double)y,x)+(int)pow((double)x,y); if(leylandDegeri==sayi) return true; if(leylandDegeri>sayi) break; return false; void Lecture7::Fonksiyon3(int alt,int ust) cout<<"ARALIKTAKI LEYLAND SAYILAR\n"; for(int i=alt;i<=ust;i++) if(Fonksiyon2(i)) cout<<i<<" Bir Leyland Sayisidir.\n"; void Lecture7::Fonksiyon4(int *ptr,int boyut) cout<<"DINAMIK DIZIDEKI LEYLAND SAYILAR\n"; if(Fonksiyon2(ptr[i])) cout<<"Dizinin "<<i+1<<". Elemani" <<"("<<*(ptr+i)<<") Bir Leyland Sayisidir.\n";
#include "Lecture7.h" #include <iostream>//cout,cin ve endl #include <cstdlib> //rand ve srand #include <ctime> //time using namespace std; int main() { srand((unsigned)time(0)); int boyut,altLimit,ustLimit,*diziPtr; Lecture7 *nesnePtr1=new Lecture7;//Dinamik Nesne Lecture7 *nesnePtr2=new Lecture7;//Dinamik Nesne cout<<"Lutfen Boyutu, Alt ve Ust Limitleri Giriniz: "; cin>>boyut>>altLimit>>ustLimit; diziPtr=new int[boyut]; nesnePtr1->Fonksiyon1(diziPtr,boyut);//Ok Operatörü (*nesnePtr2).Fonksiyon3(altLimit,ustLimit); nesnePtr1->Fonksiyon4(diziPtr,boyut); delete [] diziPtr;//Deallocate delete nesnePtr1; //Deallocate delete nesnePtr2; //Deallocate return 0; }
İki Boyutlu Dinamik Diziler //İki Boyutlu Dinamik Dizi Manipülasyonu #include <iostream>//cout, cin ve endl #include <cstdlib> //rand ve srand #include <ctime> //time using namespace std; void MatrisinIciniRastgeleSayilarlaDoldur(int**,int,int); int main() { srand((unsigned)time(0)); int satir,sutun; cout<<"Lutfen Matrisin Satir ve Sutun Sayisini Giriniz: "; cin>>satir>>sutun; //////////////////ALLOCATION/////////////////// int **matrisPtr=new int*[satir];//Birinci Boyut for(int i=0;i<satir;i++) matrisPtr[i]=new int[sutun];//İkinci Boyut /////////////////////////////////////////////// MatrisinIciniRastgeleSayilarlaDoldur(matrisPtr,satir,sutun); cout<<"matris[0][0]="<<matrisPtr[0][0]<<endl; ///////////////DEALLOCATION//////////////////// delete [] matrisPtr[i];//Deallocate Columns delete [] matrisPtr;//Deallocate Rows return 0; } void MatrisinIciniRastgeleSayilarlaDoldur(int **mPtr,int sat,int sut) for(int i=0;i<sat;i++) for(int j=0;j<sut;j++) mPtr[i][j]=rand()%6+1; cout<<*(*(mPtr+i)+j)<<' '; cout<<endl;
İki Boyutlu Dinamik Diziler