Thursday, May 1, 2014

Pointer pada bahasa pemograman C++ (Bag 2)

Pointer aritmatika
Sama seperti pada variabel biasa, pointer juga dapat berperan sebagai operand untuk operasi aritmatika. Namun untuk membahas operator aritmatika ini, kita perlu menyinggung sedikit tentang array dengan menggunakannya sebagai contoh.
Jika kita mempunyai variabel A yang bertipe array yang berisi 5 elemen dari tipe int, maka untuk mengakses elemen-elemen array tersebut kita dapat juga menggunakan pointer (misalnya p), yaitu dengan melakukan operasi aritmatika kedalam nya.

Contoh program :

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
 //Mendeklarasikan array dari tipe int sebanyak 5 elemen
 int A[5] = {100, 200, 300, 400, 500};
 
 //Mendeklarasikan pointer p yang menunjuk ke tipe data int
 int *p;
 
 //Memerintahkan pointer p untuk menunjuk elemen array pertama
 p = &A[0];
 
 cout<<"NIlai p : "<<*p<<endl;
 
 //Melakukan operasi aritmatika (penumlahan) terhadap pointer p
 p = p + 2;
 
 cout<<"NIlai p : "<<*p<<endl;
 
 //Melakukan operasi aritmatika (pengurangan) terhadap ponter p
 p = p - 1;
 
 cout<<"NIlai p : "<<*p<<endl;
 
 system("pause");
 return 0;
}
Hasil yang akan diperoleh adalah sebagai berikut :

Menggunakan kata kunci new
Dalam bahasa C++ jika kita ingin mengalokasikan memori pada ruang yang masih kosong maka kita dapat menggunakan kata kunci new. Kata kunci ini akan diikuti oleh tipe data yang kan di alokasikan sehingga kolpiler akan mengetahui seberapa besar ruang memori yang dibutuhkan untuk proses pengalokasian tersebut. Misalkan kita ingin mengalokasikan tipe data long, maka ruang ruang memori yang dibutuhkan adalah 4 byte sedangkan jika tipe data unsigned short hanya membutuhkan 2 byte. Begitu juga untuk mengalokasikan tipe data lainnya, ruang yang dibutuhkan tentu akan berbeda pula. Pada saat kita mengalokasikan memori, alamat memori yang di alokasikan tersebut tentu akan kita simpan ke pointer, sehingga sebelumnya kita harus mendeklarasikan pointer terlebih dahulu.
Bentuk umum dari penggunaan kata kunci new adalah sebagai berikut :
nama_pointer = new tipe_data;

namun jika kita ingin mengalokasikan n buah ruang memori, maka kita menggunakan bentuk di bawah ini :
nama_pointer = new tipe_data [n];
Misalkan kita akan mengalokasikan 10 buah ruang memori dengan menggunakan tipe data long (berukuran 4 byte), maka memori yang dibutuhkan adalah 10 x 4, yaitu 40 byte.
Contoh program :

#include <iostream>
#include <cstdlib>

#define MAX 5

using namespace std;

int main()
{
 float *p1;
 int *p2;
 
 //mengalokasikan satu ruang memori dan disimpan ke pointer p1
 p1 = new float;
 //mengisikan nilai ke dalam ruang yang telah di alokasikan
 *p1 = 3.14;
 
 cout<<"Nilai *p1 : "<<*p1<<endl;
 cout<<"Nilai p1 : "<<p1<<endl;
 
 //mengalokasikan 5 buah ruang memori dan disimoan ke pointer p2
 p2 = new int [MAX];
 
 //mengisikan nilai ke dalam ruang-ruang memori
 //yg telah di alokasikan
 for (int i=0; i<5; i++)
 {
  *p2 = (i+1) * 10;
  p2 += 1;
 }
 
 //Mengembalikan pointer p2 agar kembali menunjuk ke alamat
 //dari elemen ke-0
 p2 -= 5;
 
 //menampilkan nilai dan alamat yang disimpan dalam pointer p2
 for (int i=0; i<5; i++)
 {
  cout<<"Nilai *p2 ke-"<<i<<" : "<<*p2<<endl;
  cout<<"Nilai p2 ke-"<<i<<" : "<<p2<<endl;
  p2 +=1;
 }
 
 system("pause");
 return 0;
}
Hasil programnya adalah sebagai berikut :
Apabila diamati alamat dari setiap elemen yang terdapat pada pointer p2, disitu selalu mendapat penambahan nilai 4. Hal ini disebabkan karena ukutan dari tipe data int adalah 4 byte.

Menggunakan kata kunci delete
Setelah memori yang kita alokasikan untuk keperluan tertentu sudah tidak digunakan lagi, maka sebaiknya jika mendealokasikan kebali memori tersebut. Hal ini baik utnuk menghindari terjadinya pemborosan memori. Untuk melakukan ini, C++ menyediakan kata kunci delete. Bentuk umumnya adalah seperti berikut :
delete nama_pointer;

Jika kita ingin mendealokasikan n buah ruang memorim maka kita menggunakan bentuk umum berikut :
delete [n] nama_pointer;
//atau cukup ditulis
delete [] nama_pointer;

Contoh program :

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
 int *p;
 
 //Melakukan alokasi memori
 p = new int;
 *p = 100;
 
 cout<<"Nilai *p : "<<*p<<endl;
 
 //Melakukan dealokasi memori
 delete p;
 
 cout<<"NIlai *p : "<<*p<<endl;
 
 system("pause");
 return 0;
}
Hasil yang akan diperoleh adalah sebagai berikut:

Memory Leak
Dalam pemanipulasian memori dengan menggunakan pointer, kita harus dapat mencegah terjadinya memori leak (kebocoran memori). Secara definisi memori leak dapat diartikan sebagai suatu kejadian dimana terdapat memori yang terbuang sia-sia. Artinya memori tersebut masih berisi nilai, tetapi nilai ataupun alamatnya sudah tidak dapat diakses maupun didealokasikan lagi. Hal ini tentunya akan menyebabkan pemborosan memori.

Untuk memahami konsepnya, perhatikan potongan sintaks program berikut :

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
 int *p
 
 //Mengalokasikan ruang memori danmenyimpannya
 //ke dalam pointer p
 p = new int;
 
 //Mengisikan nilai ke dalam alamat tersebut
 *p = 5;
 
 //Memerintahkan p untuk menunjuk ruang memori yang baru
 p = new int;
 
 //Mengisikan nilai ke dalam alamat yang baru
 *p = 30;
 
 system("pause");
 return 0;
}
Mula-mula pointer p menunjuk ke alamat memori yang dialokasikan pertama kali dan mengisikan nilai kedalam alamat tersebut dengan nilai 5. Misalkan alamat tersebut saya namakan alamat ke-1. Selanjutnya, tanpa mendealokasikan alamat ke-1 telebih dahulu, program di atas memerintahkan pointer p untuk menunjuk ke alamat yang lain yang baru di alokasikan, yaitu alamat ke-2. Hal ini tentu akan menyebabkan alamat ke-2 (serta nilai yang terdapat di dalamnya) tidak dapat diakses maupun di alokasika lagi. Kejadian semacam ini yang dinamakan dengan memori leak. Untuk mencegah kejadian itu, sebelum memerintahkan p untuk menunjuk ke alamat ke-2 seharusnya kita mendealokasikan alamat ke-1 terlebih dahulu, sehingga memori tidak akan terbuang percuma. Oleh karena itu program di atas seharusnya ditulis seperti berikut :

#include <iostream>
#include <cstdlib>

using namespace std;

int main()
{
 int *p;
 
 //Melakukan alokasi ruang memori dan menyimpannya
 //kedalam pointer p
 p = new int;
 
 *p = 100;
 
 //Mendealokasikan terlebih dahulu alamat yang ditunjuk oleh
 //pointer p
 delete p;
 
 //Memerintahkan p untuk menunjuk ke ruang memori yang baru
 p = new int;
 
 //Mengisikan nilai ke dalam alamat yang baru
 *p = 25;
 
 cout<<"NIlai *p : "<<*p<<endl;
 
 system("pause");
 return 0;
}

Hasilnya adalah sebagai berikut :