Dangling pointer merupakan momok yang cukup berat bagi pemula C++. Dan tampaknya, terkadang expert pun mungkin mengalami sedikit kesulitan. Jangan-jangan alasan mengapa diciptakannya Programming Language yang Managed adalah untuk menghindari Dangling Pointer, hehe, maybe :p
Dangling pointer itu sendiri ada pointer yang menunjuk ke alamat yang tidak valid. Biasanya tidak validnya itu disebabkan oleh sudah terdeletenya object pada alamat memori tersebut. Untuk lebih jelas, perhatikan kode berikut:
#include <iostream>
using namespace std;
class SomeCls
{ public:
SomeCls(){ cout << "SomeCls hidup\n"; }
void Call(){ cout << "SomeCls.Call() called\n"; }
};
int main(int argc, char* argv[])
{
SomeCls* tInstance = new SomeCls();
SomeCls* tPtrInstance = tInstance;
delete tInstance;
tInstance = NULL;
if(tInstance == NULL)
{
cout << "tInstance terdelete\n" ;
}
else
{
tInstance->Call();
}
if(tPtrInstance == NULL)
{
cout << "tPtrInstance null\n" ;
}
else
{
cout << "WHAT?!!\n";
tPtrInstance->Call();
}
return 0;
}
pada kode diatas, tPtrInstance merupakan pointer yang Dangling, karena alamat tempat ia menunjuk, yaitu tInstance, telah didelete sebelumnya. Bahayanya, tPtrInstance == NULL akan menghasilkan boolean false, karena tPtrInstance tidak menunjuk NULL, namun suatu alamat yang tidak valid. Segmentation fault adalah akibat dari dangling pointer ini.
Jujur Aku sendiri belum berhasil mengatasi sepenuhnya persoalan ini, namun terdapat 1 trik yang cukup membantu, yaitu Reference to Pointer of Class. Perhatikan kode berikut:
//cut karena sama
int main(int argc, char* argv[])
{
SomeCls* tInstance = new SomeCls();
SomeCls*& tPtrInstance = tInstance;
//cut juga karena sama dengan diatas
dengan menambahkan ‘dan’ (‘&’) pada deklarasi tPtrInstance, hasilnya menjadi jauh berbeda.
output untuk kode pertama kira kira seperti ini:
SomeCls hidup tInstance terdelete WHAT?!! SomeCls.Call() called
kode diatas dijalankan di windows mungkin sementara aman, namun secara logik memang salah. Di linux, baris terakhir tidak akan muncul dan digantikan dengan ‘segmentation fault’
sedangkan untuk kode kedua akan ber-output:
SomeCls hidup tInstance terdelete tPtrInstance null
tPtrInstance dikenali sebagai NULL. Tidak seperti kode sebelumnya yang berbahaya.
Mengapa demikian? hal ini karena tPtrInstance bukan merupakan pointer, tapi reference ke suatu pointer. Karena dia reference, apabila pointer yang dialiaskan/direfer NULL, maka ia akan ikut NULL. Saatnya Refactoring, hehe.