Bagikan ke: Twitter | Facebook | LinkedIn
Daftar isi
Pendahuluan
bahasa c dan c++ memiliki caranya sendiri dalam mengelola memori, perbedaannya adalah jika bahasa C mengelola memori secara manual tetapi di bahasa c++ kita dapat mengggunakan metode RAII.
Manual Memory C Program
dalam bahasa C kita dapat mengelola memori heap dengan beberapa cara,
diantaranya adalah menggunakan fungsi malloc
, calloc
, realloc
dan
free
yang berasal dari stdlib.h
.
fungsi free
digunakan untuk membebaskan memori yang di alokasikan
malloc
malloc digunakan untuk mengalokasikan memori pada memori heap, malloc
memerlukan input size_t
dan mengembalikan void*
yang artinya fungsi
malloc mengembalikan sebuah alamat memori dan fungsi malloc memerlukan
input untuk berapa besar memori yang akan dialokasikan.
#include <stdio.h>
#include <stdlib.h>
int main() {
int size = sizeof(int);
int *n = (int*) malloc(size*1);
*n = 10;
("value : %d\n", *n);
printf("addr : %p\n", n);
printf
(n);
freereturn 0;
}
pada program diatas kita harus memgkonversi tipe void*
ke int*
agar
kita dapat menaruh isi di dalamnya kita juga secara manual harus
menggunakan fungsi free
untuk membersihkan memori yang kita pakai.
calloc
calloc memiliki fungsi yang hampir sama dengan malloc yang membedakan di
sini adalah calloc memberikan value awal pada memori yang di alokasikan,
jika kita menggunakan malloc
memori yang kita alokasikan akan berisi
sebuah angka/huruf random.
calloc juga mengembalikan sebuah tipe yang sama dengan malloc yaitu
void*
, namun calloc memerlukan 2 buat input yaitu berapa element yang
dialokasikan dan ukuran dari data yang di alokasikan.
#include <stdio.h>
#include <stdlib.h>
int main() {
int size = sizeof(int);
int *n = (int*) calloc(size, size*1);
*n = 10;
("value : %d\n", *n);
printf("addr : %p\n", n);
printf
(n);
freereturn 0;
}
dari kode diatas fungsi calloc membunyai input ukuran tipe data yang ingin di alokasikan dan berapa jumlahnya.
realloc
realloc digunakan untuk mengubah ukuran memori yang di alokasikan oleh
alloc
dan calloc
, realloc mengambil 2 buah input yaitu alamat memori
dan ukuran baru yang akan di alokasikan.
#include <stdio.h>
#include <stdlib.h>
int main() {
int size = sizeof(int);
int *n = (int*) calloc(size, size*1);
*n = 10;
("value : %d\n", *n);
printf("addr : %p\n", (void *)n);
printf("size : %lu\n", sizeof(int));
printf
= realloc(n, size*2);
n ("size : %lu\n", sizeof(int)*2);
printf
(n);
freereturn 0;
}
jika kode di atas di jalankan maka ukuran memori pada variable n akan berubah yang sebelumnya 4 menjadi 8, karena ukuran dari tipe data int disini adalah 4.
Mengelola Memory C++
C++ memiliki 2 buah fungsi yang digunakan untuk mengalokasikan memori
yaitu new
dan delede
, kita tidak perlu memberikan berapa memori yang
kita perlukan, C++ akan otomatis mengalokasikannya untuk kita.
#include <iostream>
int main(){
int* holder = new int(42);
std::cout << *holder
<< std::endl;
delete holder;
return 0;
}
Strategi Memori C++
terdapat masalah pada kode-kode diatas yang biasanya terjadi pada bahasa program yang mulakukan pengolahan memori secara manual, diantaranya adalah Dangling pointer dan Double Free
Dangling Pointer adalah sebuah pointer yang tidak menunjuk sebuah memori.
#include <iostream>
#include <cstdio>
int main() {
int *dp = NULL;
{
int c = 10;
= &c;
dp ("%p\n", dp);
printf}
("%p\n", dp);
printf("%d\n", *dp);
printfreturn 0;
}
kode diatas kita mencoba mengaksesk alamat memori sebuah variable yang berada diluar scope, bayangkan apa yang terjadi jika alamat memori yang kita gunakan digunakan oleh program lain ?.
salah satu masalah lain adalah double free yaitu dimana kita melakukan pembersihan memori yang sudah dibersihkan.
#include <iostream>
int main() {
int* ptr = new int;
*ptr = 10;
delete ptr;
delete ptr;
return 0;
}
kode diatas melakukan pembersihan pada variable ptr 2 kali, apa yang terjadi jika proggram lain sedang berjalan menggunakan alamat memori ptr, maka program itu akan terjadi error dan akan sulit mencari bug.
RAII
di dalam bahasa C++ terdapat sebuah tehnik yang dinamakan RAII atau (Resource acquisition is initialization) dimana kita bisa melakukan pembersihan memori pada Destructor.
destructor adalah sebuah fungsi digunakan untuk membersihkan sumber daya yang telah dialokasikan pada saat objek dibuat.
#include <iostream>
class IntHolder {
private:
int* m_value;
public:
(int value) {
IntHolderm_value = new int(value);
}
~IntHolder() {
delete m_value;
}
int getValue() const {
return *m_value;
}
};
int main() {
= IntHolder(42);
IntHolder holder std::cout << holder.getValue()
<< std::endl;
return 0;
}
Smart Pointer
C++ memiliki sebuah fitur yang membuat mengelola memori menjadi lebih
mudah, diantaranya adalah std::unique_ptr
dan std::shared_ptr
, perlu
diingat bahwa std::unique_ptr
dan std::shared_ptr
merupakan sebuah
fitur c++ dengan standar C++11 dan juga kita perlu mengimport memory
header.
std::unique_ptr
adalah sebuah konsep yang mirip dengan Rust Borrow
system yaitu sebuah object hanya memiliki 1 sebuah resource, contoh
menggunakan std::unique_ptr
#include <iostream>
#include <memory>
int main() {
std::unique_ptr<int> ptr(new int);
*ptr = 10;
std::cout << "Nilai pointer: "
<< *ptr
<< std::endl;
return 0;
}
std::shared_ptr
hampir sama dengan konsep Rust Reference Counting (Rc)
yaitu pointer yang dapat digunakan oleh beberapa objek untuk membagikan
kepemilikan pada suatu resource. Ketika tidak ada lagi objek yang
memiliki kepemilikan pada resource, maka resource akan dihapus, contoh
std::shared_ptr
#include <iostream>
#include <memory>
class MyClass {
public:
void doSomething() {
std::cout << "Melakukan sesuatu!"
<< std::endl;
}
};
int main() {
std::shared_ptr<MyClass> ptr1(new MyClass);
std::shared_ptr<MyClass> ptr2 = ptr1;
->doSomething();
ptr1->doSomething();
ptr2
std::cout << "Jumlah pointer yang mengacu ke objek: "
<< ptr1.use_count()
<< std::endl;
return 0;
}
Daftar Pustaka
Wikipedia
→ Dangling PointerCommon Weakness Enumeration (CWE)
→ CWE-415: Double Free
→ CWE-825: Expired Pointer Dereference
→ CWE-416: Use After FreeCommon Vulnerabilities and Exposures (CVE)
→ CVE-2014-1776Wallhaven
→ blue eyes, blonde, anime, c++, programming, New Game!