Alokasi Memori Yuliana Setiowati
Alokasi Memori Menyediakan fasilitas untuk membuat ukuran buffer dan array secara dinamik. Dinamik artinya bahwa ruang dalam memori akan dialokasikan ketika program dieksekusi (run time) Fasilitas ini memungkinkan user untuk membuat tipe data dan struktur dengan ukuran dan panjang berapapun yang disesuaikan dengan kebutuhan di dalam program.
sizeof() Untuk mendapatkan ukuran dari berbagai tipe data, variabel ataupun struktur. Return value : ukuran dari obyek yang bersangkutan dalam byte. Parameter dari sizeof() : sebuah obyek atau sebuah tipe data
main() { int myInt; Employee john; printf("Size of int is %d\n",sizeof(myInt)); printf("Size of int is %d\n",sizeof(int)); printf("Size of Employee is %d\n",sizeof(Employee)); printf("Size of john is %d\n",sizeof(john)); printf("Size of char is %d\n",sizeof(char)); printf("Size of short is %d\n",sizeof(short)); printf("Size of long is %d\n",sizeof(long)); printf("Size of float is %d\n",sizeof(float)); printf("Size of double is %d\n",sizeof(double)); return 0; } typedef struct employee_st { char name[40]; int id; } Employee;
Hasil Program
Fungsi malloc() Return value : Untuk mengalokasikan memori Bentuk prototypenya adalah void *malloc(int jml_byte); Return value : Berhasil : sebuah pointer yang tak bertipe (pointer to void) yang menunjuk ke buffer yang dialokasikan Gagal : return value berupa sebuah pointer NULL. Pointer tersebut haruslah dikonversi kepada tipe yang sesuai (dengan menggunakan type cast) agar bisa mengakses data yang disimpan dalam buffer.
main() { char s1[] = "This is a sentence"; char *pblok; pblok = (char *) malloc(strlen(s1) + 1); if (pblok == NULL) printf("Error on malloc\n"); else { strcpy(pblok,s1); printf("s1: %s\n", s1); printf("pblok: %s\n", pblok); return 0; } }
malloc( ) int *p; double *q; Date *r; p = (int*) malloc(sizeof(int)); q = (double*) malloc(sizeof(double)); r = (Date*) malloc(sizeof(Date)); 3 *p 3.14 *q 2 *r 2002 p r q
malloc( ), closer look int *p; p = (int*) malloc(sizeof(int)); sizeof(int) = the number of bytes occupied by an int int *p; p = (int*) malloc(sizeof(int)); Malloc mengalokasikan storage dengan ukuran 4 byte (int) p = (int*) malloc(…) Pointer tersebut haruslah dikonversi kepada tipe yang sesuai
malloc( ) ? #include <stdlib.h> int main () { p int *p; int a=2; p = (int*) malloc(sizeof(int)); *p = 4; *p += a; … free(p); p = NULL; } p ? *p p Menghapus sel yang ditunjuk p
Fungsi free() Jika bekerja dengan menggunakan memori yang dialokasikan secara dinamis, maka memori harus dibebaskan kembali setelah selesai digunakan untuk dikembalikan kepada sistem. Setelah suatu ruang memori dibebaskan, ruang tersebut bisa dipakai lagi untuk alokasi variabel dinamis lainnya. Bentuk deklarasi void free(void *pblok); dengan pblok adalah pointer yang menunjuk ke memori yang akan dibebaskan. Dalam hal ini, pointer pblok tidak perlu di-cast kembali ke void terlebih dahulu. Compiler otomatis telah menangani proses ini.
Fungsi free() main() { char *pblok; pblok = (char *) malloc(500 * sizeof(char)); if (pblok == NULL) puts("Error on malloc"); else { puts("OK, alokasi memori sudah dilakukan"); puts("------"); free(pblok); puts("Blok memori telah dibebaskan kembali"); }
free( ) ? ? #include <stdlib.h> int main () { p int *p; int a=2; p = (int*) malloc(sizeof(int)); *p = 4; *p += a; … free(p); p = NULL; } p ? *p p p ? Menghapus sel yang ditunjuk p Pada saat variabel dinamik tidak digunakan lagi kita perlu membebaskannya. Kompiler tidak mendealokasi storage space secara otomatis
NULL ? ? #include <stdlib.h> int main () { p int *p; int a=2; p = (int*) malloc(sizeof(int)); *p = 4; *p += a; … free(p); p = NULL; } p ? *p p p ? p
#include <stdlib.h> int main () { int *p; int a=2; p = (int*) malloc(sizeof(int)); *p = 4; *p += a; … free(p); p = NULL; } Menggunakan fungsi malloc(), free() dan NULL harus mengincludekan stdlib.h.
*q = *p int *p, *q; p = (int*)malloc(sizeof(int)); q = (int*)malloc(sizeof(int)); *p = 3; *q = *p; *p p 3 3 *q q
q = p *p p 3 int *p, *q; p = (int*) malloc(sizeof(int)); q = (int*) malloc(sizeof(int)); *p = 3; q = p; *q q 3 *q *p p q
Example ? ? r q *q *p p *r r q *q p r q *q p (A) 3 r 6 q *q *p p *r (A) #include <stdlib.h> int main () { int *p, *q; int *r; p = (int*) malloc(sizeof(int)); r = p; q = (int*) malloc(sizeof(int)); *p = 3; *q = *p + *r; (A) free(r); (B) r = NULL; (C) } (B) r 6 q *q p ? (C) r 6 q *q p ?
Latihan #include <stdlib.h> int main () { int *p, *q; int *r; int *s; p = (int*) malloc(sizeof(int)); r = p; *p = 5; q = p; s = r; *q = *s + 1; *r = *p * 2; (A) free(r); r = NULL; free(q); q = NULL; (B) }
Memory Leak #include <stdlib.h> int main () { int *p, *q; p = (int*) malloc(sizeof(int)); *p = 1+2; (A) scanf("%d", p); (B) free(p); p = NULL; (C) } p 3 *p (A) p (B) 3 q = p; or free(p); 8 *p p (C) 3 Pada saat p=NULL; maka *p tidak dapat diakses lagi
Pointer yang tidak valid #include <stdlib.h> int main () { int *p, *q; p = (int*) malloc(sizeof(int)); q = p; *q = 3; (A) free(q); q = NULL; (B) } 3 q *p p *q (A) (B) q p ? printf("%d %d", *p, *q); *p = 999; *q = 999; Setelah free(q), sel *p (dan *q) tidak ada. Oleh sebab itu kita tidak dapat menggunakan *p atau *q.
Free sel yang tidak digunakan hanya satu kali #include <stdlib.h> int main () { int *p, *q; p = (int*) malloc(sizeof(int)); q = p; *q = 3; (A) free(q); q = NULL; (B) p = NULL; (C) } 3 q *p p *q (A) (B) q p ? free(p); (C) q p Free untuk tiap sel yang tidak digunakan hanya dilakukan satu kali (Bukan free tiap pointer satu kali)
Jangan Free() Variabel Static #include <stdlib.h> int main () { int *p, *q; int a = 5; p = (int*) malloc(sizeof(int)); q = &a; *p = 3; (A) free(p); p = NULL; (B) q = NULL; (C) } 5 q *p p *q (A) 3 a (B) q p 5 *q a free(q); (C) q p 5 a Kita hanya perlu membebaskan variabel dinamik. Bukan variabel biasa. Ingat Free() untuk malloc() saja.
Fungsi realloc() Untuk mengalokasikan ulang memori yang dipesan Fungsi ini akan mengalokasikan kembali pointer yang sebelumnya telah diatur untuk menunjuk sejumlah lokasi, memberinya ukuran yang baru (bisa jadi lebih kecil atau lebih besar). Bentuk deklarasi : ... pblok = (char *) malloc(500 * sizeof(char)); pblok = realloc(pblok, 600 * sizeof(char));
Fungsi realloc() fungsi ini memberikan return value berupa pointer yang sama, meng-copy data lama ke lokasi baru dan mengarahkan pointer ke sejumlah lokasi baru tersebut membebaskan blok memori yang lama. Jika berhasil : melakukan relokasi baru. Jika tidak berhasil : return value berupa NULL. Cara terbaik adalah mengecek hasil realloc() untuk memastikan hasilnya bukan NULL pointer, sebelum kemudian menumpuki pointer lama dengan return value dari realloc().