Lompat ke konten Lompat ke sidebar Lompat ke footer

Layout Memori Bahasa C dan Penjelasannya

Pada pemrograman bahasa C, pada umumnya representasi memoris dari sebuah program terdiri dari beberapa bagian, yaitu: Segmen Teks, Inisialisasi Segmen Data, Uninisialisasi Segmen Data, Heap, dan Stack.


Sebelum memahami lebih dalam materi tentang Layout Memori Bahasa C dan Penjelasannya, terlebih dahulu pelajari materi tentang: Pengurutan Struct Bahasa C Beserta Contoh Programnya, Compound Literals Bahasa C Beserta Penjelasannya, dan Anonimus Union dan Struct Bahasa C dan Penjelasannya.

Tipikal memori layout dari proses yang berjalan:

satu, Segmen Teks: segmen teks atau juga dikenal sebagai sebuah kode segmen atau teks, merupakan salah satu dari section program pada file objek atau memori, yang terdiri dari instruksi eksekusi program. Sebagai bagian dari sebuah memori, teks segmen dapat ditempatkan dibagian bawah dari heap atau stack dalam urutan tertentu untuk mencegah heap dan stack mengalami overflow ketika melakukan overwrite.

Umumnya, teks segmen dapat dibagikan ke bagian lain sehingga hanya cukup menggunakan satu file saja dalam sebuah memori untuk dieksekusi secara berkali-kali dalam program, seperti teks editor, kompilator bahasa C, shells, dan lain sebagainya. Selain itu, segmen teks seringkali bersifat read-only, untuk mencegah program mengubah instruksinya secara tidak sengaja.

dua, Inisialisasi Data Segmen: inisialisasi data segmen secara sederhana disebut sebagai data segmen. Sebuah data segmen adalah sebuah bagian dari ruang alamat virtual dari suatu program, yang mengandung variabel global dan variabel static yang diinisialisasi oleh programmer.

Catatan: data segmen hanya bersifat read-only, karena nilai variabel dapat diubah pada saat dijalankan. Segmen ini juga dapat lebih jauh diklasifikasikan menjadi area inisialisasi read-only dan area inisialisasi read-write. Contohnya, string global yang didefinisikan oleh char char s[] = "hello world" pada bahasa C, dan sebuah statemen bahasa C seperti int debug=1 yang berada di luar fungsi main dapat disimpan pada area inisialisasi read-write. Juga, sebuah statemen global bahasa C seperti const char* string = "hello world" dapat membuat string literal "hello world" menjadi dapat disimpan pada area inisialisasi read-only, dan variabel karakter pointer string pada area inisialisasi read-write. Contoh lainnya, static int i = 10 dan variabel global int i = 10 dapat disimpan pada data segmen.

tiga, Uninisialisasi Data Segmen: uninisialisasi data segmen umumnya disebut sebagai "bss" segmen, dinamai dari operator assembler kuno yang merupakan singkatan dari "block started by symbol" Data, yang diinisialisasi oleh kernel ke aritmatika 0 sebelum program mulai mengeksekusi data yang tidak diinisialisasi dimulai pada akhir segmen data, dan berisi semua variabel global, dan variabel statis yang diinisialisasi ke nol atau tidak memiliki inisialisasi eksplisit dalam kode sumber. Contoh: sebuah deklarasi variabel static int i; dapat dikandung pada BSS segment dan sebuah deklarasi variabel int j; dapat dikandung pada BSS segment.

empat, Stack: Stack umumnya selalu berdampingan dengan area heap dan berkembang pada arah yang berlawanan, dimana ketika pointer stack bertemu dengan pointer heap, maka alokasi memori akan dibebaskan.

Catatan: dengan ruang alamat memori modern yang lebih besar yang disertai dengan teknik memori virtual, stack mungkin dapat digantikan pada hampir semua bagian bahasa pemrograman, tetapi penggunaannya akan tetap berkembang dalam arah yang berlawanan. Area stack mengandung program stack, dimana sebuah struktur LIFO umumnya berlokasi pada bagian memori yang lebih tinggi. Pada standar arsitektur PC komputer x86, stack akan berkembang bergerak ke arah alamat nol; sedangkan pada arsitektur lainnya, stack akan berkembang ke arah yang berlawanan. Sebuah rute register "stack pointer" pada bagian atas stack, itu disesuaikan setiap kali nilai "didorong" ke stack. Kumpulan nilai akan didorong untuk sebuah fungsi pemanggilan disebut juga sebagai "stack frame". Sebuah frame stack terdiri dari nilai minimum dari sebuah alamat return. Stack merupakan tempat dimana variabel secara otomatis akan disimpan bersamaan dengan informasi yang disimpan setiapkali sebuah fungsi dipanggil. Setiap kali sebuah fungsi dipanggil, alamat dari fungi tersebut dikembalikan dan informasi lainnya tentang lingkungan pemanggilnya, seperti mesin register, akan disimpan pada Stack. Fungsi yang baru saja dipanggil akan dialokasikan dalam sebuah ruangan pada stack secara otomatis dan merupakan variabel sementara. Dengan cara ini, maka fungsi rekursif dapat bekerja pada bahasa C, dimana setiap kali sebuah fungsi rekursif dipanggil oleh fungsi itu sendiri, maka sebuah frame stack baru akan digunakan, sehingga sekumpulan variabel tidak perlu dilibatkan dengan variabel baru saat ini dari instance lainnya dari sebuah fungsi yang sedang dipanggil tersebut.

lima, Heap: Heap adalah suatu segmen dimana alokasi memori dinamis umumnya akan ditempatkan. Area heap dimulai pada bagian akhir dari segmen BSS dan berkembang menjadi alamat yang lebih besar dari alamat sebelumnya. Area heap diatur oleh malloc, realloc, dan free, yang mungkin saja menggunakan sistem pemanggilan brk dan sbrk untuk menyesuaikan nilai ukurannya. Penggunaan brk dan sbrk dan sebuah area heap tunggal adalah tidak diharuskan untuk memenuhi kontrak malloc, realloc, atau free. Namun, hal tersebut mungkin saja dapat diimplementasikan menggunakan mmap untuk menyiapkan bagian potensial tidak berkelanjutan dari memori virtual ke proses ruanga alamat virtual. Area Heap dibagikan oleh semua librari bahasa C dan secara dinamis memuat modul dalam prosesnya.

Contoh: perintah melaporkan nilai ukuran dalam satuan byte dari teks, data, dan segmen bss.

#include <stdio.h>

int main(void)

{return 0;}

Tambahkan sebuah variabel global pada program, kemudian periksa nilai ukuran dari bss.

Contoh:

#include <stdio.h>

/* Uninisialisasi variabel yang disimpan dalam BSS*/

int global; 

int main(void)

{return 0;}

Tambahkan sebuah varaibel static yang juga disimpan pada bss.

Contoh:

#include <stdio.h>


/* Variabel inisialisasi yang

 disimpan dalam BSS*/

int global; 


int main(void)

{

/* Uninitialized static

 variable stored in bss */

static int i; 

return 0;

}

Tambahkan inisialisasi variabel static yang kemudian disimpan pada Data Segmen (DS).

Contoh:

#include <stdio.h>


/* Uninisialisasi variabel

 yang disimpan dalam BSS */

int global; 


int main(void)

{

/* Inisialisasi variabel

 static yang disimpan di dalam

 DS*/

static int i = 100

return 0;

}

Inisialisasikan sebuah variabel global yang kemudian disimpan pada Data Segmen (DS).

Contoh:

#include <stdio.h>


/* Inisialisasi variabel

 global yang disimpan dalam DS

 */

int global = 10


int main(void)

{

/* Inisialisasi variabel

 static yang disimpan dalam DS

 */

static int i = 100


return 0;

}



Dalam dunia pemrograman menggunakan bahasa C, pemahaman tentang layout memori sangat penting, baik untuk pengelolaan sumber daya yang efisien maupun untuk optimasi kinerja aplikasi. Layout memori merujuk pada cara program dan data disusun dalam memori komputer. Pengetahuan tentang hal ini dapat membantu programmer dalam menulis kode yang lebih efisien dan mencegah terjadinya kesalahan yang terkait dengan alokasi memori yang salah.

Memori dalam komputer, secara umum, terdiri dari beberapa area atau segmen yang memiliki tujuan dan fungsi yang berbeda. Dalam konteks bahasa C, layout memori dibagi menjadi beberapa bagian yang memisahkan data, kode, dan bagian lain yang menyimpan informasi penting tentang proses yang sedang berjalan. Memahami segmen-segmen ini sangat berguna, terutama ketika berurusan dengan alokasi dinamis, pointer, atau ketika mencoba mengoptimalkan penggunaan memori pada sistem dengan sumber daya terbatas.

Segmen Memori dalam Bahasa C

Secara garis besar, memori program dalam bahasa C dapat dibagi menjadi lima segmen utama. Setiap segmen memiliki fungsi khusus yang berhubungan dengan data dan instruksi dalam program. Adapun segmen-segmen tersebut adalah:
  • Segmen Kode (Text Segment): Segmen kode adalah tempat dimana instruksi program disimpan. Ketika program dieksekusi, CPU akan mengambil instruksi dari segmen ini. Sebagai bagian dari layout memori, segmen ini umumnya bersifat hanya baca (read-only) untuk mencegah perubahan tak terduga pada kode yang sedang berjalan. Penyimpanan di segmen kode biasanya tidak dipengaruhi oleh alokasi dinamis atau variabel lokal yang digunakan dalam program.
  • Segmen Data (Data Segment): Segmen data digunakan untuk menyimpan data statis yang diketahui pada saat kompilasi. Variabel global dan statis, baik yang diinisialisasi maupun tidak diinisialisasi, ditempatkan di segmen ini. Segmen data terbagi lagi menjadi dua bagian:  
    •  Inisialisasi: Untuk variabel global atau statis yang sudah diberi nilai awal.  
    •  Tanpa Inisialisasi (BSS - Block Started by Symbol): Untuk variabel global atau statis yang belum diinisialisasi secara eksplisit oleh programmer, yang secara otomatis akan diinisialisasi dengan nilai default (biasanya nol).
  • Segmen Tumpukan (Stack Segment): Segmen tumpukan adalah area memori yang digunakan untuk menyimpan data terkait dengan pemanggilan fungsi. Tumpukan digunakan untuk menyimpan variabel lokal, parameter fungsi, serta alamat pengembalian setelah fungsi selesai dieksekusi. Setiap kali fungsi dipanggil, tumpukan akan bertambah (push), dan setiap kali fungsi selesai, tumpukan akan berkurang (pop). Pengelolaan tumpukan dilakukan secara otomatis oleh sistem operasi, dan ukuran segmen ini terbatas oleh sistem, yang bisa menyebabkan masalah seperti *stack overflow* jika terlalu banyak memori yang digunakan.
  • Segmen Heap (Heap Segment): Segmen heap adalah area memori yang digunakan untuk alokasi dinamis. Berbeda dengan tumpukan, yang pengelolaannya otomatis, alokasi di segmen heap dilakukan secara eksplisit oleh programmer melalui fungsi alokasi memori seperti *malloc*, *calloc*, atau *realloc*. Memori yang dialokasikan di heap harus dikelola dengan hati-hati untuk menghindari kebocoran memori (*memory leak*) atau penggunaan memori yang sudah dibebaskan. Sebagai contoh, setelah penggunaan memori dinamis selesai, programmer perlu memastikan bahwa memori tersebut dibebaskan menggunakan fungsi *free*.
  • Segmen Pengaturan (Memory-Mapped Segment): Segmen ini digunakan untuk memetakan file atau perangkat keras tertentu ke dalam ruang alamat memori. Ini memungkinkan program untuk mengakses file atau perangkat keras tersebut seolah-olah adalah bagian dari memori utama, meningkatkan efisiensi dalam hal akses data.

Manajemen Memori dalam Bahasa C

Bahasa C memberi kebebasan yang besar dalam hal pengelolaan memori, tetapi dengan kebebasan tersebut datang pula tanggung jawab besar. Salah pengelolaan memori dapat menyebabkan berbagai masalah serius, seperti kebocoran memori, akses memori yang tidak sah, atau kegagalan aplikasi. Oleh karena itu, pemahaman yang baik tentang bagaimana memori dikelola dalam bahasa C sangat penting.

Memori yang digunakan dalam program C dapat dibagi menjadi dua kategori utama: memori statis dan memori dinamis.
  • Memori Statis: Memori statis adalah memori yang dialokasikan pada waktu kompilasi dan memiliki waktu hidup yang sebanding dengan durasi eksekusi program. Variabel global, variabel statis, dan konstanta disimpan di segmen data atau segmen kode. Alokasi dan pembebasan memori ini terjadi secara otomatis, sehingga programmer tidak perlu khawatir tentang pengelolaannya selama eksekusi program.
  • Memori Dinamis: Memori dinamis adalah memori yang dialokasikan selama waktu eksekusi program dengan menggunakan fungsi seperti *malloc* atau *calloc*. Keuntungan utama dari memori dinamis adalah kemampuannya untuk dialokasikan atau dibebaskan sesuai dengan kebutuhan program. Namun, hal ini menuntut perhatian khusus terhadap pembebasan memori untuk mencegah kebocoran memori, dimana memori yang sudah tidak digunakan lagi tetap tersimpan, menghabiskan sumber daya.

Alokasi Memori dan Pointer

Dalam bahasa C, pointer memainkan peran yang sangat penting dalam manajemen memori. Pointer adalah variabel yang menyimpan alamat memori, dan dengan menggunakan pointer, programmer dapat mengakses dan memanipulasi data di lokasi memori tertentu. Pointer memungkinkan akses langsung ke memori, yang membuatnya sangat efisien, tetapi juga berisiko jika digunakan secara tidak hati-hati.

Alokasi memori dinamis melalui pointer memungkinkan program untuk menangani data yang jumlahnya tidak diketahui pada saat kompilasi, serta memanipulasi blok memori sesuai dengan kebutuhan. Namun, kesalahan dalam penggunaan pointer, seperti dereferensi pointer yang tidak valid atau lupa membebaskan memori, dapat menyebabkan masalah serius dalam aplikasi.

Masalah Umum dalam Manajemen Memori

Salah satu masalah yang sering muncul dalam manajemen memori di bahasa C adalah *memory leak*, yaitu kondisi dimana memori yang sudah tidak digunakan lagi tidak dibebaskan. Ketika memori tidak dibebaskan setelah selesai digunakan, maka memori tersebut akan tetap teralokasi dan tidak dapat digunakan kembali oleh program atau sistem operasi, yang dapat menyebabkan penggunaan memori yang berlebihan dan bahkan memperlambat sistem seiring berjalannya waktu.

Selain itu, masalah seperti *segmentation fault* atau akses ke memori yang tidak sah sering kali terjadi ketika pointer digunakan secara tidak benar. Ini biasanya disebabkan oleh dereferensi pointer yang mengarah ke alamat yang tidak valid, seperti pointer yang tidak diinisialisasi atau yang sudah dibebaskan.

Pengelolaan Memori dan Kinerja

Pengelolaan memori yang baik sangat berpengaruh terhadap kinerja sebuah aplikasi. Sebagai contoh, penggunaan memori yang efisien dalam bahasa C dapat mengurangi waktu eksekusi, menghindari terjadinya kegagalan sistem, dan memastikan bahwa aplikasi dapat berjalan pada berbagai platform dan perangkat dengan sumber daya terbatas.

Salah satu teknik untuk mengoptimalkan penggunaan memori adalah dengan menggunakan struktur data yang tepat dan efisien. Selain itu, manajemen memori dinamis yang baik juga dapat dilakukan dengan menggunakan algoritma dan strategi pengelolaan memori yang tepat, seperti *garbage collection* untuk memudahkan pembebasan memori yang tidak lagi digunakan, meskipun bahasa C tidak menyediakan mekanisme garbage collection secara otomatis seperti bahasa pemrograman lain.

Kesimpulan

Layout memori dalam bahasa C adalah aspek fundamental yang harus dipahami dengan baik untuk menulis program yang efisien dan bebas dari kesalahan. Pemahaman yang mendalam tentang segmen-segmen memori, pengelolaan memori statis dan dinamis, serta penggunaan pointer dengan bijak, sangat diperlukan agar program dapat berjalan dengan optimal. Selain itu, penting juga untuk menghindari masalah umum dalam manajemen memori, seperti kebocoran memori dan akses ke lokasi memori yang tidak valid, yang bisa mengganggu kinerja aplikasi dan menyebabkan crash.

Dengan pemahaman yang baik tentang layout memori, programmer dapat membuat keputusan yang lebih tepat dalam mengelola sumber daya, serta menulis kode yang lebih efisien dan aman.


Artikel ini telah dibaca oleh: Firamika, Galang Prayoga, Gerald Hugo Christano, Gladys Sanditya, dan Gustina Aruming Sekar Lati.

5 komentar untuk "Layout Memori Bahasa C dan Penjelasannya"

  1. Apa yang dimaksud dengan layout memori bahasa C?

    BalasHapus
    Balasan
    1. Layout memori atau tata letak memori pada bahasa C merupakan program bahasa C yang berisi lima segmen yaitu stack, heap, BSS, DS, dan segmen teks, dimana setiap segmen tersebut memiliki izin baca, tulis, dan eksekusi sendiri.

      Hapus
  2. Bagaimana proses layout memori pada Bahasa C?

    BalasHapus
    Balasan
    1. Layout memori ditata secara berurutan pada nilai dasar 0 dan seterusnya untuk satu byte setiap kali. Setiap posisi dalam memori memiliki nomornya masing-masing yang disebut sebagai alamat memori.

      Hapus
    2. Kompilator akan mengaitkan nama variabel yang ada tersebut dengan alamat memori sesuai dengan urutan layout memori pada Bahasa C.

      Hapus

Hubungi admin melalui Wa : +62-896-2414-6106

Respon komentar 7 x 24 jam, mohon bersabar jika komentar tidak langsung dipublikasi atau mendapatkan balasan secara langsung.

Bantu admin meningkatkan kualitas blog dengan melaporkan berbagai permasalahan seperti typo, link bermasalah, dan lain sebagainya melalui kolom komentar.

- Ikatlah Ilmu dengan Memostingkannya -
- Big things start from small things -