Perbedaan antara malloc dan calloc?

780

Apa perbedaan antara melakukan:

ptr = (char **) malloc (MAXELEMS * sizeof(char *));

atau:

ptr = (char **) calloc (MAXELEMS, sizeof(char*));

Kapan sebaiknya menggunakan calloc over malloc atau sebaliknya?

pengguna105033
sumber
8
Dalam C, Anda dapat menulis di atas secara lebih umum sebagai:ptr = calloc(MAXELEMS, sizeof(*ptr));
chqrlie
7
Posting yang menarik tentang perbedaan antara calloc dan malloc + memset vorpus.org/blog/why-does-calloc-exist
ddddavidee
2
@dddavidee Saya juga menemukan blog itu setelah saya tidak puas dengan begitu banyak jawaban di internet. Nathaniel J. Smith pantas mendapatkan 100+ poin SO untuk analisisnya.
lifebalance

Jawaban:

851

calloc()memberi Anda buffer nol diinisialisasi, sementara malloc()meninggalkan memori tidak diinisialisasi.

Untuk alokasi besar, sebagian besar callocimplementasi di bawah OS mainstream akan mendapatkan halaman-halaman yang diketahui dari OS (misalnya melalui POSIX mmap(MAP_ANONYMOUS)atau Windows VirtualAlloc) sehingga tidak perlu menuliskannya di ruang pengguna. Ini adalah cara normal mallocmendapatkan lebih banyak halaman dari OS juga; callochanya memanfaatkan jaminan OS.

Ini berarti callocmemori masih bisa "bersih" dan dialokasikan dengan malas, dan copy-on-write dipetakan ke halaman fisik nol bersama sistem. (Dengan asumsi sistem dengan memori virtual.)

Beberapa kompiler bahkan dapat mengoptimalkan malloc + memset (0) menjadi calloc untuk Anda, tetapi Anda harus menggunakan calloc secara eksplisit jika Anda ingin memori dibaca sebagai 0.

Jika Anda tidak akan pernah membaca memori sebelum menulisnya, gunakan mallocsehingga dapat (berpotensi) memberi Anda memori kotor dari daftar bebas internalnya alih-alih mendapatkan halaman baru dari OS. (Atau alih-alih mem-blok memori pada daftar gratis untuk alokasi kecil).


Implementasi tertanam dari callocmungkin membiarkannya callocsendiri ke memori nol jika tidak ada OS, atau itu bukan OS multi-pengguna yang mewah yang nol halaman untuk menghentikan kebocoran informasi antara proses.

Pada embedded Linux, malloc bisa mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS), yang hanya diaktifkan untuk beberapa kernel tertanam karena tidak aman pada sistem multi-pengguna.

Fred Larson
sumber
224
Varian * alokasi cukup mnemonik - alokasi jelas, alokasi memori, alokasi ulang.
Cascabel
43
Gunakan malloc () jika Anda akan mengatur semua yang Anda gunakan di ruang yang dialokasikan. Gunakan calloc () jika Anda akan membiarkan bagian-bagian dari data tidak diinisialisasi - dan akan menguntungkan jika bagian-bagian yang belum disetel disetarakan.
Jonathan Leffler
268
callocbelum tentu lebih mahal, karena OS dapat melakukan beberapa trik untuk mempercepatnya. Saya tahu bahwa FreeBSD, ketika mendapat waktu CPU yang tidak digunakan, menggunakannya untuk menjalankan proses sederhana yang hanya berputar dan mengeluarkan blok memori yang tidak dapat dialokasikan, dan menandai blok dengan demikian memproses dengan sebuah flag. Jadi ketika Anda melakukannya calloc, itu pertama-tama mencoba untuk menemukan salah satu dari blok pre-zeroed tersebut dan hanya memberikannya kepada Anda - dan kemungkinan besar itu akan menemukannya.
Pavel Minaev
28
Saya cenderung merasa bahwa jika kode Anda menjadi "lebih aman" sebagai akibat dari alokasi nol-initing secara default, maka kode Anda tidak cukup aman apakah Anda menggunakan malloc atau calloc. Menggunakan malloc adalah indikator yang baik bahwa data memerlukan inisialisasi - Saya hanya menggunakan calloc dalam kasus di mana 0 byte itu sebenarnya bermakna. Perhatikan juga bahwa calloc tidak selalu melakukan apa yang Anda pikirkan untuk tipe non-char. Tidak ada yang benar-benar menggunakan representasi jebakan lagi, atau non-IEEE mengapung, tapi itu bukan alasan untuk berpikir kode Anda benar-benar portabel ketika tidak.
Steve Jessop
18
@SteveJessop "Safer" bukan kata yang tepat. Saya pikir "Deterministik" adalah istilah yang lebih baik. Kode yang lebih deterministik daripada memiliki kegagalan yang bergantung pada waktu dan urutan data, akan lebih mudah untuk mengisolasi kegagalan. Calloc kadang-kadang cara mudah untuk mendapatkan determinisme itu, versus inisialisasi eksplisit.
dennis
362

Perbedaan yang kurang diketahui adalah bahwa dalam sistem operasi dengan alokasi memori optimis, seperti Linux, penunjuk yang dikembalikan malloctidak didukung oleh memori nyata hingga program benar-benar menyentuhnya.

callocmemang menyentuh memori (itu menulis nol di atasnya) dan dengan demikian Anda akan yakin OS mendukung alokasi dengan RAM aktual (atau swap). Ini juga mengapa lebih lambat dari malloc (tidak hanya harus nol itu, OS juga harus menemukan area memori yang sesuai dengan mungkin menukar proses lain)

Lihat misalnya pertanyaan SO ini untuk diskusi lebih lanjut tentang perilaku malloc

Isak Savo
sumber
49
calloctidak perlu menulis nol. Jika blok yang dialokasikan sebagian besar terdiri dari nol halaman baru yang disediakan oleh sistem operasi, itu dapat membuat mereka tidak tersentuh. Ini tentu saja perlu callocdisetel ke sistem operasi daripada fungsi perpustakaan umum di atas malloc. Atau, implementor dapat callocmembandingkan setiap kata dengan nol sebelum mem-nolkannya. Ini tidak akan menghemat waktu, tetapi itu akan menghindari mengotori halaman baru.
R .. GitHub BERHENTI MEMBANTU ICE
3
@R .. catatan menarik. Namun dalam praktiknya, apakah implementasi seperti itu ada di alam liar?
Isak Savo
10
dlmallocImplementasi all- like melewatkan memsetjika chunk diperoleh melalui mmaping anonim baru (atau setara). Biasanya jenis alokasi ini digunakan untuk potongan yang lebih besar, mulai dari 256k atau lebih. Saya tidak tahu ada implementasi yang melakukan perbandingan terhadap nol sebelum menulis nol selain dari saya sendiri.
R .. GitHub BERHENTI MEMBANTU ICE
1
omallocjuga melewatkan memset; calloctidak perlu menyentuh halaman apa pun yang belum pernah digunakan oleh aplikasi (cache halaman), selamanya. Padahal, implementasi yang sangat primitifcalloc berbeda.
mirabilos
10
kalib glibc memeriksa apakah ia mendapatkan memori segar dari OS. Jika demikian, ia tahu itu TIDAK perlu menulisnya, karena mmap (..., MAP_ANONYMOUS) mengembalikan memori yang sudah memusatkan perhatian.
Peter Cordes
112

Salah satu keuntungan yang sering diabaikan callocadalah bahwa (implementasi konforman) itu akan membantu melindungi Anda terhadap kerentanan integer overflow. Membandingkan:

size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);

vs.

size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);

Yang pertama dapat menghasilkan alokasi kecil dan buffer overflow berikutnya, jika countlebih besar dari SIZE_MAX/sizeof *bar. Yang terakhir akan secara otomatis gagal dalam hal ini karena objek yang besar tidak dapat dibuat.

Tentu saja Anda mungkin harus mencari implementasi yang tidak sesuai yang mengabaikan kemungkinan overflow ... Jika ini merupakan masalah pada platform yang Anda targetkan, Anda harus melakukan tes manual untuk overflow.

R .. GitHub BERHENTI MEMBANTU ICE
sumber
17
Rupanya overflow aritmatika itulah yang menyebabkan lubang OpenSSH pada tahun 2002. Artikel bagus dari OpenBSD mengenai bahaya ini dengan fungsi yang berhubungan dengan memori: undeadly.org/cgi?action=article&sid=20060330071917
Philip P.
4
@KomradeP .: Menarik. Sayangnya artikel yang Anda tautkan memiliki informasi yang salah di awal. Contoh dengan charini tidak overflow melainkan konversi pelaksanaan yang ditetapkan ketika menetapkan hasil kembali menjadi charobjek.
R .. GitHub BERHENTI MEMBANTU ICE
Mungkin ada di sana hanya untuk ilustrasi. Karena kompiler kemungkinan akan mengoptimalkannya. Milik saya mengkompilasi ke dalam asm ini: push 1.
Philip P.
1
@tristopia: Intinya bukan bahwa kode dapat dieksploitasi pada semua implementasi, tetapi bahwa itu salah tanpa asumsi tambahan dan dengan demikian tidak benar / penggunaan portabel.
R .. GitHub BERHENTI MEMBANTU ICE
3
@tristopia: Jika mode berpikir Anda adalah " size_t64-bit jadi itu tidak masalah", itu cara berpikir yang cacat yang akan mengarah pada bug keamanan. size_tadalah tipe abstrak yang mewakili ukuran, dan tidak ada alasan untuk berpikir produk arbitrer dari nomor 32-bit dan size_t(catatan: sizeof *barpada prinsipnya bisa lebih besar dari 2 ^ 32 pada implementasi C 64-bit!) cocok size_t.
R .. GitHub BERHENTI MEMBANTU ICE
37

Dokumentasi membuat calloc terlihat seperti malloc, yang hanya menginisialisasi-nol memori; ini bukan perbedaan utama! Gagasan calloc adalah abstact semantik copy-on-write untuk alokasi memori. Ketika Anda mengalokasikan memori dengan calloc itu semua peta ke halaman fisik yang sama yang diinisialisasi ke nol. Ketika salah satu halaman dari memori yang dialokasikan ditulis ke dalam halaman fisik dialokasikan. Ini sering digunakan untuk membuat tabel hash BESAR, misalnya karena bagian hash yang kosong tidak didukung oleh memori tambahan (halaman); mereka dengan senang hati menunjuk ke halaman tanpa inisialisasi tunggal, yang bahkan dapat dibagikan di antara proses.

Setiap penulisan ke alamat virtual dipetakan ke halaman, jika halaman itu adalah halaman nol, halaman fisik lain dialokasikan, halaman nol disalin di sana dan aliran kontrol dikembalikan ke proses klien. Ini berfungsi dengan cara yang sama memori memetakan file, memori virtual, dll bekerja .. menggunakan paging.

Berikut adalah satu cerita pengoptimalan tentang topik ini: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/

t0rakka
sumber
26

Tidak ada perbedaan dalam ukuran blok memori yang dialokasikan. callochanya mengisi blok memori dengan pola fisik semua-nol-bit. Dalam praktiknya sering diasumsikan bahwa objek yang terletak di blok memori yang dialokasikan dengan callocnilai initilial seolah-olah mereka diinisialisasi dengan literal 0, yaitu integer harus memiliki nilai 0, variabel floating-point - nilai 0.0, pointer - nilai null-pointer yang sesuai , dan seterusnya.

Dari sudut pandang pedantic, calloc(dan juga memset(..., 0, ...)) hanya dijamin untuk menginisialisasi objek (dengan nol) dengan benar unsigned char. Segala sesuatu yang lain tidak dijamin diinisialisasi dengan benar dan mungkin mengandung apa yang disebut representasi perangkap , yang menyebabkan perilaku tidak terdefinisi. Dengan kata lain, untuk semua tipe selain unsigned charpatterma semua-nol-bit yang disebutkan di atas mungkin mewakili nilai ilegal, representasi trap.

Kemudian, di salah satu Teknis Corrigenda ke standar C99, perilaku didefinisikan untuk semua tipe integer (yang masuk akal). Yaitu secara formal, dalam bahasa C saat ini Anda hanya dapat menginisialisasi tipe integer dengan calloc(dan memset(..., 0, ...)). Menggunakannya untuk menginisialisasi hal lain dalam kasus umum mengarah ke perilaku yang tidak terdefinisi, dari sudut pandang bahasa C.

Dalam praktiknya, callocberfungsi, seperti yang kita semua ketahui :), tetapi apakah Anda ingin menggunakannya (mengingat di atas) terserah Anda. Saya pribadi lebih suka menghindarinya sepenuhnya, gunakan mallocsaja dan lakukan inisialisasi saya sendiri.

Akhirnya, detail penting lainnya adalah yang callocdiperlukan untuk menghitung ukuran blok akhir secara internal , dengan mengalikan ukuran elemen dengan jumlah elemen. Saat melakukan itu, callocharus memperhatikan kemungkinan aritmatika meluap. Ini akan menghasilkan alokasi yang gagal (pointer nol) jika ukuran blok yang diminta tidak dapat dihitung dengan benar. Sementara itu, mallocversi Anda tidak berusaha untuk menonton meluap. Ini akan mengalokasikan sejumlah memori yang "tidak dapat diprediksi" jika terjadi overflow.

Semut
sumber
Per paragraf "detail penting lainnya": yang tampaknya membuat memset(p, v, n * sizeof type);masalah karena n * sizeof typemungkin meluap. Kira saya perlu menggunakan for(i=0;i<n;i++) p[i]=v;loop untuk kode yang kuat.
chux - Reinstate Monica
Akan sangat membantu jika ada sarana standar dimana kode dapat menyatakan bahwa suatu implementasi harus menggunakan semua-bit-nol sebagai pointer nol (menolak kompilasi sebaliknya), karena ada implementasi yang menggunakan representasi null-pointer lainnya, tetapi mereka relatif jarang; kode yang tidak harus dijalankan pada implementasi seperti itu bisa lebih cepat jika dapat menggunakan calloc () atau memset untuk menginisialisasi array pointer.
supercat
@ chux Tidak, jika array dengan nelemen ada di mana elemen memiliki ukuran sizeof type, maka n*sizeof typetidak bisa meluap, karena ukuran maksimum objek apa pun harus kurang dari SIZE_MAX.
12431234123412341234123
@ 12431234123412341234123 Benar tentang ukuran array <= SIZE_MAX, namun tidak ada array di sini. Pointer yang dikembalikan dari calloc()kaleng menunjuk ke memori yang dialokasikan melebihi SIZE_MAX. Banyak implementasi yang membatasi produk dari 2 args to calloc()to SIZE_MAX, namun spesifikasi C tidak memaksakan batas itu.
chux - Reinstate Monica
21

dari artikel Benchmarking bersenang-senang dengan calloc () dan nol halaman di Blog Georg Hager

Saat mengalokasikan memori menggunakan calloc (), jumlah memori yang diminta tidak langsung dialokasikan. Sebaliknya, semua halaman yang termasuk dalam blok memori terhubung ke satu halaman yang berisi semua nol oleh beberapa sihir MMU (tautan di bawah). Jika halaman tersebut hanya dibaca (yang berlaku untuk array b, c dan d dalam versi asli dari tolok ukur), data disediakan dari halaman nol tunggal, yang - tentu saja - cocok dengan cache. Begitu banyak untuk kernel loop yang terikat memori. Jika sebuah halaman ditulis (tidak peduli bagaimana), kesalahan terjadi, halaman "nyata" dipetakan dan halaman nol disalin ke memori. Ini disebut copy-on-write, pendekatan optimasi yang terkenal (yang saya bahkan telah mengajar beberapa kali dalam kuliah C ++ saya). Setelah itu,

Ashish Chavan
sumber
dimana tautannya?
Rupesh Yadav.
2
baris jawaban pertama berisi tautan ke Blog Georg Hager.
Ashish Chavan
11

callocumumnya malloc+memsetke 0

Biasanya sedikit lebih baik untuk digunakan malloc+memsetsecara eksplisit, terutama ketika Anda melakukan sesuatu seperti:

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

Itu lebih baik karena sizeof(Item)diketahui oleh kompiler pada waktu kompilasi dan kompiler dalam kebanyakan kasus akan menggantinya dengan instruksi terbaik ke nol memori. Di sisi lain jika memsetterjadi calloc, ukuran parameter alokasi tidak dikompilasi dalam callockode dan memsetsering disebut, yang biasanya berisi kode untuk mengisi byte-by-byte hingga batas panjang, daripada siklus untuk mengisi memori dalam sizeof(long)potongan dan akhirnya byte-by-byte mengisi ruang yang tersisa. Bahkan jika pengalokasi cukup pintar untuk memanggil beberapa aligned_memsetitu masih akan menjadi loop umum.

Satu pengecualian penting adalah ketika Anda melakukan malloc / calloc dari memori yang sangat besar (beberapa power_of_two kilobyte) di mana alokasi kasus dapat dilakukan langsung dari kernel. Karena kernel OS biasanya akan mem-nol semua memori yang mereka berikan untuk alasan keamanan, calloc yang cukup pintar mungkin akan mengembalikannya tanpa menambahkan zeroing tambahan. Sekali lagi - jika Anda hanya mengalokasikan sesuatu yang Anda tahu kecil, Anda mungkin lebih baik dengan malloc + memset kinerja-bijaksana.

virco
sumber
+1 untuk pengingat bahwa implementasi generik fungsionalitas di pustaka sistem tidak harus lebih cepat dari operasi yang sama dalam kode pengguna.
Patrick Schlüter
1
Ada juga poin kedua yang membuat calloc()lebih lambat daripada malloc(): perkalian untuk ukuran. calloc()diperlukan untuk menggunakan perkalian generik (jika size_t64 bit bahkan 64 bit yang sangat mahal * 64 bit = 64 bit operasi) sedangkan malloc () akan sering memiliki konstanta waktu kompilasi.
Patrick Schlüter
4
glibc calloc memiliki beberapa kecerdasan untuk memutuskan bagaimana cara paling efisien menghapus potongan yang dikembalikan, mis. kadang-kadang hanya sebagian saja yang perlu dibersihkan, dan juga yang belum dibuka hingga ukuran 9 * (size_t). Memori adalah memori, membersihkannya 3 byte sekaligus tidak akan menjadi lebih cepat hanya karena Anda akan menggunakannya untuk menyimpannya struct foo { char a,b,c; };. callocselalu lebih baik daripada malloc+ memset, jika Anda akan menghapus seluruh mallocwilayah ed. callocmemiliki pemeriksaan yang cermat tetapi efisien untuk int overflow dalam elemen ukuran * juga.
Peter Cordes
8

Perbedaan 1:

malloc() biasanya mengalokasikan blok memori dan ini adalah segmen memori yang diinisialisasi.

calloc() mengalokasikan blok memori dan menginisialisasi semua blok memori ke 0.

Perbedaan 2:

Jika Anda mempertimbangkan malloc()sintaks, hanya diperlukan 1 argumen. Perhatikan contoh berikut di bawah ini:

data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );

Mis: Jika Anda ingin mengalokasikan 10 blok memori untuk tipe int,

int *ptr = (int *) malloc(sizeof(int) * 10 );

Jika Anda mempertimbangkan calloc()sintaks, itu akan membutuhkan 2 argumen. Perhatikan contoh berikut di bawah ini:

data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));

Mis: jika Anda ingin mengalokasikan 10 blok memori untuk tipe int dan Inisialisasi semua itu ke NOL,

int *ptr = (int *) calloc(10, (sizeof(int)));

Kesamaan:

Keduanya malloc()dan calloc()akan mengembalikan void * secara default jika tidak diketik.!

Shivaraj Bhat
sumber
Dan mengapa Anda membuat data_type dan cast_type berbeda?
Habis Terjual
7

Ada dua perbedaan.
Pertama, ada dalam jumlah argumen. malloc()membutuhkan satu argumen (memori diperlukan dalam byte), sementara calloc()membutuhkan dua argumen.
Kedua, malloc()tidak menginisialisasi memori yang dialokasikan, sementara calloc()menginisialisasi memori yang dialokasikan ke NOL.

  • calloc()mengalokasikan area memori, panjangnya akan menjadi produk dari parameternya. callocmengisi memori dengan NOL dan mengembalikan pointer ke byte pertama. Jika gagal menemukan ruang yang cukup itu mengembalikan NULLpointer.

Sintaks: ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block); yaituptr_var=(type *)calloc(n,s);

  • malloc()mengalokasikan satu blok memori dari REQUSTED SIZE dan mengembalikan pointer ke byte pertama. Jika gagal menemukan jumlah memori yang dibutuhkan, ia mengembalikan pointer nol.

Sintaks: ptr_var=(cast_type *)malloc(Size_in_bytes); The malloc()Fungsi mengambil satu argumen, yang merupakan jumlah byte untuk mengalokasikan, sedangkan calloc()fungsi membutuhkan dua argumen, salah satunya adalah jumlah elemen, dan yang lainnya adalah jumlah byte untuk mengalokasikan untuk masing-masing elemen tersebut. Juga, calloc()inisialisasi ruang yang dialokasikan menjadi nol, sementara malloc()tidak.

Jainendra
sumber
6

The calloc()fungsi yang dideklarasikan di <stdlib.h>header yang menawarkan beberapa keunggulan dibandingkan malloc()fungsi.

  1. Ini mengalokasikan memori sebagai sejumlah elemen dari ukuran yang diberikan, dan
  2. Ini menginisialisasi memori yang dialokasikan sehingga semua bit nol.
Vipin Diwakar
sumber
6

malloc()dan calloc()merupakan fungsi dari pustaka standar C yang memungkinkan alokasi memori dinamis, artinya keduanya memungkinkan alokasi memori selama runtime.

Prototipe mereka adalah sebagai berikut:

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

Terutama ada dua perbedaan antara keduanya:

  • Perilaku: malloc()mengalokasikan blok memori, tanpa menginisialisasi, dan membaca konten dari blok ini akan menghasilkan nilai-nilai sampah. calloc(), di sisi lain, mengalokasikan blok memori dan menginisialisasi ke nol, dan jelas membaca konten blok ini akan menghasilkan nol.

  • Sintaks: malloc()mengambil 1 argumen (ukuran untuk dialokasikan), dan calloc()mengambil dua argumen (jumlah blok yang dialokasikan dan ukuran masing-masing blok).

Nilai kembali dari keduanya adalah pointer ke blok memori yang dialokasikan, jika berhasil. Jika tidak, NULL akan dikembalikan yang menunjukkan kegagalan alokasi memori.

Contoh:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

Fungsi yang sama seperti yang calloc()dapat dicapai menggunakan malloc()dan memset():

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

Catatan yang malloc()lebih disukai digunakan calloc()karena lebih cepat. Jika inisialisasi nol nilai diinginkan, gunakan calloc()sebagai gantinya.

Elmiomar
sumber
5

Perbedaan yang belum disebutkan: batas ukuran

void *malloc(size_t size)hanya dapat mengalokasikan hingga SIZE_MAX.

void *calloc(size_t nmemb, size_t size);dapat mengalokasikan sekitar SIZE_MAX*SIZE_MAX.

Kemampuan ini tidak sering digunakan di banyak platform dengan pengalamatan linier. Sistem seperti membatasi calloc()dengan nmemb * size <= SIZE_MAX.

Pertimbangkan jenis 512 byte yang dipanggil disk_sectordan kode ingin menggunakan banyak sektor. Di sini, kode hanya dapat digunakan hingga SIZE_MAX/sizeof disk_sectorsektor.

size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);

Pertimbangkan hal-hal berikut yang memungkinkan alokasi yang lebih besar.

size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);

Sekarang jika sistem seperti itu dapat memasok alokasi yang begitu besar adalah masalah lain. Sebagian besar hari ini tidak akan. Namun itu telah terjadi selama bertahun-tahun ketika SIZE_MAX65535. Diberikan hukum Moore , menduga ini akan terjadi sekitar 2030 dengan model memori tertentu dengan SIZE_MAX == 4294967295dan kumpulan memori dalam 100 GBytes.

chux - Pasang kembali Monica
sumber
2
Secara umum, size_t akan mampu menampung ukuran objek terbesar yang bisa ditangani oleh suatu program. Sebuah sistem di mana size_t adalah 32 bit tidak mungkin mampu menangani alokasi yang lebih besar dari 4294967295 byte, dan sistem yang akan mampu menangani alokasi yang ukurannya hampir pasti akan membuat size_tlebih besar dari 32 bit. Satu-satunya pertanyaan adalah apakah menggunakan callocdengan nilai-nilai yang produknya melebihi SIZE_MAXdapat diandalkan untuk menghasilkan nol daripada mengembalikan pointer ke alokasi yang lebih kecil.
supercat
Setuju tentang generalisasi Anda , namun spesifikasi C memungkinkan calloc()alokasi melebihi SIZE_MAX. Itu telah terjadi di masa lalu dengan 16-bit size_tdan karena memori terus memudar, saya tidak melihat alasan itu tidak akan terjadi bahkan jika itu tidak umum .
chux - Reinstate Monica
1
Standar C memungkinkan kode untuk meminta alokasi yang ukurannya melebihi SIZE_MAX. Jelas tidak mensyaratkan bahwa ada keadaan di mana alokasi semacam itu mungkin berhasil; Saya tidak yakin ada manfaat khusus dari mandat bahwa implementasi yang tidak dapat menangani alokasi tersebut harus dikembalikan NULL(terutama mengingat bahwa beberapa implementasi memiliki mallocpointer kembali ke ruang yang belum berkomitmen dan mungkin tidak tersedia ketika kode benar-benar mencoba untuk menggunakan Itu).
supercat
Lebih lanjut, di mana mungkin ada sistem di masa lalu yang jangkauan pengalamatan yang tersedia melebihi bilangan bulat terwakili terbesar, saya tidak melihat kemungkinan realistis yang pernah terjadi lagi, karena itu akan membutuhkan kapasitas penyimpanan miliaran gigabyte. Bahkan jika Hukum Moore terus berlaku, pergi dari titik di mana 32 bit berhenti menjadi cukup ke titik di mana 64 bit berhenti menjadi cukup akan memakan waktu dua kali lipat dari titik di mana 16 bit sudah cukup ke titik di mana 32 tidak 't.
supercat
1
Mengapa sebuah implementasi yang dapat menampung alokasi tunggal lebih dari 4G tidak mendefinisikan size_tke uint64_t?
supercat
2

Jumlah blok:
malloc () menetapkan satu blok memori yang diminta,
calloc () menetapkan beberapa blok memori yang diminta

Inisialisasi:
malloc () - tidak menghapus dan menginisialisasi memori yang dialokasikan.
calloc () - menginisialisasi memori yang dialokasikan oleh nol.

Kecepatan:
malloc () cepat.
calloc () lebih lambat dari malloc ().

Argumen & Sintaks:
malloc () membutuhkan 1 argumen:

  1. byte

    • Jumlah byte yang akan dialokasikan

calloc () membutuhkan 2 argumen:

  1. panjangnya

    • jumlah blok memori yang akan dialokasikan
  2. byte
    • jumlah byte yang dialokasikan pada setiap blok memori
void *malloc(size_t bytes);         
void *calloc(size_t length, size_t bytes);      

Cara Alokasi memori:
Fungsi malloc memberikan memori 'ukuran' yang diinginkan dari tumpukan yang tersedia.
Fungsi calloc memberikan memori yang berukuran sama dengan 'num * size'.

Arti nama:
Nama malloc berarti "alokasi memori".
Nama calloc berarti "alokasi yang berdekatan".

Majbah Habib
sumber