ความแตกต่างระหว่างการทำคืออะไร:
ptr = (char **) malloc (MAXELEMS * sizeof(char *));หรือ:
ptr = (char **) calloc (MAXELEMS, sizeof(char*));เมื่อใดที่ควรใช้ calloc ผ่าน malloc หรือในทางกลับกัน
ptr = calloc(MAXELEMS, sizeof(*ptr));
                ความแตกต่างระหว่างการทำคืออะไร:
ptr = (char **) malloc (MAXELEMS * sizeof(char *));หรือ:
ptr = (char **) calloc (MAXELEMS, sizeof(char*));เมื่อใดที่ควรใช้ calloc ผ่าน malloc หรือในทางกลับกัน
ptr = calloc(MAXELEMS, sizeof(*ptr));
                คำตอบ:
calloc()ให้บัฟเฟอร์แบบ zero-initialized ขณะที่malloc()ปล่อยให้หน่วยความจำไม่เริ่มต้น
สำหรับการจัดสรรขนาดใหญ่callocการใช้งานส่วนใหญ่ภายใต้ระบบปฏิบัติการหลักจะได้รับหน้าที่เป็นศูนย์จากระบบปฏิบัติการ (เช่นผ่าน POSIX mmap(MAP_ANONYMOUS)หรือ Windows VirtualAlloc) ดังนั้นจึงไม่จำเป็นต้องเขียนในพื้นที่ผู้ใช้ นี่คือวิธีที่ปกติmallocได้รับหน้าเพิ่มเติมจากระบบปฏิบัติการเช่นกัน; callocเพียงแค่ใช้ประโยชน์จากการรับประกันของระบบปฏิบัติการ
ซึ่งหมายความว่าcallocหน่วยความจำยังคงสามารถ "สะอาด" และจัดสรรแบบ lazily และคัดลอกเมื่อเขียนไปยังเพจฟิสิคัลที่แบ่งใช้ทั่วทั้งระบบของศูนย์ (สมมติว่าระบบมีหน่วยความจำเสมือน)
คอมไพเลอร์บางคนยังสามารถเพิ่มประสิทธิภาพ + memset malloc (0) เข้า calloc สำหรับคุณ แต่คุณควรใช้ calloc 0อย่างชัดเจนถ้าคุณต้องการหน่วยความจำในการอ่านเป็น
หากคุณไม่ได้อ่านหน่วยความจำก่อนที่จะเขียนให้ใช้mallocเพื่อให้ (อาจ) ให้หน่วยความจำสกปรกจากรายการฟรีภายในแทนการรับหน้าใหม่จากระบบปฏิบัติการ (หรือแทนที่จะเป็นศูนย์บล็อกหน่วยความจำในรายการฟรีสำหรับการจัดสรรขนาดเล็ก)
การใช้งานในตัวของcallocอาจทำให้callocหน่วยความจำศูนย์ถึงตัวเองถ้าไม่มีระบบปฏิบัติการหรือมันไม่ใช่ระบบปฏิบัติการที่ผู้ใช้หลายคนที่ศูนย์หน้าเพื่อหยุดการรั่วไหลของข้อมูลระหว่างกระบวนการ
บน Linux ที่ฝังตัว malloc สามารถทำได้mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS)ซึ่งเปิดใช้งานสำหรับเมล็ดในตัวบางตัวเท่านั้นเนื่องจากไม่ปลอดภัยในระบบที่มีผู้ใช้หลายคน
callocไม่จำเป็นต้องมีราคาแพงมากนักเนื่องจากระบบปฏิบัติการสามารถใช้ลูกเล่นบางอย่างเพื่อเร่งความเร็วได้ ฉันรู้ว่า FreeBSD เมื่อมันได้รับเวลา CPU ที่ไม่ได้ใช้ให้ใช้เพื่อเรียกใช้กระบวนการง่ายๆที่เพิ่งไปรอบ ๆ และ zeroes บล็อกหน่วยความจำที่จัดสรรคืนและทำเครื่องหมายบล็อกซึ่งประมวลผลด้วยแฟล็ก ดังนั้นเมื่อคุณทำเช่นcallocนั้นก่อนอื่นคุณจะพยายามหาบล็อกที่มีค่าศูนย์ก่อนหน้านี้หนึ่งบล็อกและให้มันแก่คุณ - และเป็นไปได้มากว่ามันจะหาได้
                    ความแตกต่างที่รู้จักกันน้อยคือในระบบปฏิบัติการที่มีการจัดสรรหน่วยความจำในแง่ดีเช่น Linux ตัวชี้ที่ส่งคืนโดยmallocไม่ได้รับการสนับสนุนจากหน่วยความจำจริงจนกว่าโปรแกรมจะสัมผัสจริง
callocไม่แตะต้องหน่วยความจำ (มันเขียนเลขศูนย์บน) และดังนั้นคุณจะแน่ใจได้ว่าระบบปฏิบัติการกำลังสำรองการจัดสรรด้วย RAM จริง (หรือสลับ) นี่คือสาเหตุที่ช้ากว่า malloc (ไม่เพียง แต่ต้องเป็นศูนย์เท่านั้นระบบปฏิบัติการยังต้องค้นหาพื้นที่หน่วยความจำที่เหมาะสมโดยอาจสลับกระบวนการอื่น ๆ )
ดูตัวอย่างคำถาม SO นี้สำหรับการสนทนาเพิ่มเติมเกี่ยวกับพฤติกรรมของ malloc
callocไม่จำเป็นต้องเขียนเลขศูนย์ หากบล็อกที่จัดสรรนั้นส่วนใหญ่เป็นศูนย์หน้าใหม่ที่จัดทำโดยระบบปฏิบัติการบล็อกนั้นสามารถปล่อยให้ไม่มีใครแตะต้องได้ นี้แน่นอนต้องที่จะปรับระบบปฏิบัติการมากกว่าฟังก์ชั่นห้องสมุดทั่วไปด้านบนของcalloc mallocหรือผู้ดำเนินการสามารถcallocเปรียบเทียบแต่ละคำกับศูนย์ก่อน zeroing สิ่งนี้จะไม่ประหยัดเวลา แต่จะหลีกเลี่ยงการทำให้หน้าใหม่สกปรก
                    dlmallocการใช้งานที่มีลักษณะคล้ายกันทั้งหมดข้ามขั้นตอนนี้memsetหากได้รับชิ้นผ่านmmapหน้าใหม่ที่ไม่ระบุชื่อ (หรือเทียบเท่า) โดยปกติแล้วการจัดสรรแบบนี้จะใช้สำหรับชิ้นที่ใหญ่กว่าเริ่มต้นที่ 256k หรือมากกว่านั้น ฉันไม่รู้การใช้งานที่เปรียบเทียบกับศูนย์ก่อนที่จะเขียนศูนย์นอกเหนือจากของฉันเอง
                    omallocยังข้ามmemset; callocไม่จำเป็นต้องแตะหน้าใด ๆ ที่ไม่ได้ใช้งานโดยแอปพลิเคชัน (แคชหน้า) ตลอดไป แม้ว่าการใช้งานดั้งเดิมมากcallocแตกต่างกัน
                    ข้อดีอย่างหนึ่งที่มักถูกมองข้ามcallocก็คือ (การใช้งานตามมาตรฐาน) ซึ่งจะช่วยปกป้องคุณจากช่องโหว่จำนวนเต็มล้น เปรียบเทียบ:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);เมื่อเทียบกับ
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);อดีตอาจส่งผลให้การจัดสรรขนาดเล็กและหน่วยความจำล้นที่ตามมาหากมีค่ามากกว่าcount SIZE_MAX/sizeof *barหลังจะล้มเหลวโดยอัตโนมัติในกรณีนี้เนื่องจากวัตถุที่ไม่สามารถสร้างขนาดใหญ่
แน่นอนคุณอาจต้องระวังการใช้งานที่ไม่สอดคล้องซึ่งละเลยความเป็นไปได้ของการล้น ... หากนี่เป็นข้อกังวลเกี่ยวกับแพลตฟอร์มที่คุณกำหนดเป้าหมายคุณจะต้องทำการทดสอบด้วยตนเองสำหรับการโอเวอร์โฟลว์ต่อไป
charคือไม่ล้น แต่แปลงการดำเนินงานที่กำหนดไว้เมื่อกำหนดกลับผลเป็นcharวัตถุ
                    size_tเป็น 64- บิตดังนั้นจึงไม่มีปัญหา" นั่นเป็นวิธีคิดที่สมบูรณ์แบบที่จะนำไปสู่ข้อบกพร่องด้านความปลอดภัย size_tเป็นประเภทนามธรรมที่แสดงถึงขนาดและมีเหตุผลที่จะคิดว่าสินค้าโดยพลการของจำนวน 32 บิตและไม่มีsize_t(หมายเหตุ: sizeof *barสามารถในหลักการจะสูงกว่า 2 ^ 32 ในการดำเนินงาน C 64 บิต) size_tพอดีใน
                    เอกสารทำให้ calloc มีลักษณะเหมือน malloc ซึ่งเพิ่งเริ่มต้นใช้หน่วยความจำไม่เป็นศูนย์ นี่ไม่ใช่ความแตกต่างหลัก! แนวคิดของ calloc คือการยกเลิกความหมายของ copy-on-write สำหรับการจัดสรรหน่วยความจำ เมื่อคุณจัดสรรหน่วยความจำด้วย calloc มันแผนที่ทั้งหมดไปยังหน้าทางกายภาพเดียวกันซึ่งเริ่มต้นเป็นศูนย์ เมื่อเพจใด ๆ ของหน่วยความจำที่จัดสรรถูกเขียนลงในฟิสิคัลเพจจะถูกจัดสรร มักใช้เพื่อสร้างตารางแฮชขนาดใหญ่ตัวอย่างเช่นเนื่องจากส่วนของแฮชที่ว่างเปล่าไม่ได้รับการสนับสนุนจากหน่วยความจำเพิ่มเติม (หน้า) พวกเขาชี้ไปที่หน้าเริ่มต้นเป็นศูนย์เดียวอย่างมีความสุขซึ่งสามารถแบ่งปันได้ระหว่างกระบวนการ
การเขียนไปยังที่อยู่เสมือนใด ๆ จะถูกแมปไปยังหน้าถ้าหน้านั้นเป็นหน้าศูนย์หน้าทางกายภาพอื่นได้รับการจัดสรรหน้าศูนย์จะถูกคัดลอกที่นั่นและการไหลของการควบคุมจะถูกส่งกลับไปยังกระบวนการไคลเอนต์ วิธีนี้ใช้งานได้เช่นเดียวกับไฟล์ที่แมปหน่วยความจำหน่วยความจำเสมือน ฯลฯ ใช้ .. การเพจ
นี่คือเรื่องราวการเพิ่มประสิทธิภาพหนึ่งเรื่องเกี่ยวกับหัวข้อ: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/
ขนาดของบล็อกหน่วยความจำที่จัดสรรไม่แตกต่างกัน callocเพียงเติมบล็อกหน่วยความจำด้วยรูปแบบศูนย์ทั้งหมดบิตแบบฟิสิคัล ในทางปฏิบัติมันมักจะสันนิษฐานว่าวัตถุที่อยู่ในบล็อกหน่วยความจำที่จัดสรรด้วยcallocมีค่าเริ่มต้นราวกับว่าพวกเขาเริ่มต้นด้วยตัวอักษร0เช่นจำนวนเต็มควรมีค่า0ตัวแปรตัวแปรจุดลอยตัว - มูลค่าของ0.0ตัวชี้ - ค่าตัวชี้โมฆะที่เหมาะสม และอื่น ๆ
จากจุดอวดความรู้ในมุมมองของ แต่calloc(เช่นเดียวกับmemset(..., 0, ...)) จะรับประกันเฉพาะที่จะต้องเริ่มต้น (มีเลขศูนย์) unsigned charวัตถุชนิด ทุกอย่างอื่นไม่รับประกันว่าจะเริ่มต้นอย่างถูกต้องและอาจมีการเรียกว่าการเป็นตัวแทนกับดักซึ่งทำให้พฤติกรรมที่ไม่ได้กำหนด กล่าวอีกนัยหนึ่งสำหรับประเภทอื่นใดนอกเหนือunsigned charจาก patterm all-zero-bits ดังกล่าวข้างต้นอาจเป็นตัวแทนของค่าที่ผิดกฎหมายการเป็นตัวแทนกับดัก
ต่อมาในหนึ่งใน Corrigenda ทางเทคนิคถึงมาตรฐาน C99 พฤติกรรมถูกกำหนดไว้สำหรับจำนวนเต็มทุกประเภท (ซึ่งสมเหตุสมผล) นั่นคืออย่างเป็นทางการในภาษา C ปัจจุบันคุณสามารถเริ่มต้นประเภทจำนวนเต็มด้วยcalloc(และmemset(..., 0, ...)) การใช้มันเพื่อเริ่มต้นสิ่งอื่นในกรณีทั่วไปนำไปสู่พฤติกรรมที่ไม่ได้กำหนดจากมุมมองของภาษา C
ในทางปฏิบัติcallocงานเรารู้ :) แต่ไม่ว่าคุณต้องการใช้ (พิจารณาข้างต้น) ขึ้นอยู่กับคุณ โดยส่วนตัวฉันชอบที่จะหลีกเลี่ยงมันอย่างสมบูรณ์ใช้mallocแทนและทำการเริ่มต้นของตัวเอง
ในที่สุดรายละเอียดที่สำคัญอีกอย่างหนึ่งก็callocคือต้องใช้การคำนวณขนาดบล็อกขั้นสุดท้ายภายในโดยการคูณขนาดองค์ประกอบด้วยจำนวนองค์ประกอบ ในขณะที่ทำเช่นนั้นcallocต้องคอยระวังโอเวอร์โฟลว์ทางคณิตศาสตร์ มันจะทำให้การจัดสรรไม่สำเร็จ (ตัวชี้โมฆะ) หากไม่สามารถคำนวณขนาดบล็อกที่ร้องขอได้อย่างถูกต้อง ในขณะที่mallocรุ่นของคุณไม่พยายามดูมากเกินไป มันจะจัดสรรจำนวนหน่วยความจำที่ "คาดเดาไม่ได้" ในกรณีที่เกิดโอเวอร์โฟลว์
memset(p, v, n * sizeof type);เกิดปัญหาเพราะn * sizeof typeอาจล้น เดาว่าฉันจะต้องใช้การfor(i=0;i<n;i++) p[i]=v;วนซ้ำสำหรับโค้ดที่มีประสิทธิภาพ
                    nองค์ประกอบอยู่ที่องค์ประกอบที่มีขนาดsizeof typeแล้วn*sizeof typeไม่สามารถล้นเพราะขนาดสูงสุดของวัตถุใด ๆ SIZE_MAXที่จะต้องน้อยกว่า
                    SIZE_MAXแต่ยังไม่มีอาร์เรย์ที่นี่ ตัวชี้ที่ส่งคืนจากcalloc()สามารถชี้ไปยังหน่วยความจำที่จัดสรรเกินSIZE_MAXได้ การนำไปใช้งานหลายอย่าง จำกัด ผลิตภัณฑ์ของ 2 args ไปcalloc()ที่SIZE_MAXแต่ C spec ไม่ได้กำหนดขีด จำกัด นั้น
                    จากบทความการเปรียบเทียบสนุกกับ calloc () และศูนย์หน้าในบล็อกของ Georg Hager
เมื่อจัดสรรหน่วยความจำโดยใช้ calloc () จำนวนหน่วยความจำที่ร้องขอจะไม่ถูกจัดสรรทันที หน้าทั้งหมดที่เป็นของบล็อกหน่วยความจำจะเชื่อมต่อกับหน้าเดียวที่มีเลขศูนย์ทั้งหมดด้วยเวทมนตร์ MMU (ลิงก์ด้านล่าง) หากหน้าดังกล่าวเป็นเพียงการอ่าน (ซึ่งเป็นจริงสำหรับอาร์เรย์ b, c และ d ในเวอร์ชันมาตรฐานเดิม) ข้อมูลจะถูกจัดเตรียมจากหน้าศูนย์เดียวซึ่งแน่นอนว่าเหมาะกับแคช มากสำหรับเคอร์เนลวนหน่วยความจำที่ถูกผูกไว้ หากหน้าถูกเขียนไปยัง (ไม่ว่าจะเกิดอะไรขึ้น) จะเกิดความผิดพลาดหน้า“ ของจริง” จะถูกแมปและหน้าศูนย์จะถูกคัดลอกไปยังหน่วยความจำ สิ่งนี้เรียกว่า copy-on-write ซึ่งเป็นวิธีการเพิ่มประสิทธิภาพที่เป็นที่รู้จักกันดี (ซึ่งฉันได้สอนหลายครั้งในการบรรยาย C ++) หลังจากนั้น,
calloc โดยทั่วไป malloc+memset 0
โดยทั่วไปจะดีกว่าเล็กน้อยที่จะใช้malloc+memsetอย่างชัดเจนโดยเฉพาะเมื่อคุณทำสิ่งที่ชอบ:
ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));นั่นเป็นสิ่งที่ดีกว่าเพราะsizeof(Item)รู้ว่าคอมไพเลอร์ ณ เวลารวบรวมและคอมไพเลอร์ส่วนใหญ่จะแทนที่ด้วยคำแนะนำที่ดีที่สุดเท่าที่จะเป็นไปได้สำหรับหน่วยความจำศูนย์ ในทางกลับกันหากmemsetเกิดขึ้นcallocขนาดพารามิเตอร์ของการจัดสรรจะไม่ถูกรวบรวมในcallocรหัสและmemsetมักจะเรียกจริงซึ่งมักจะมีรหัสที่จะทำไบต์ - by - byte เติมจนขอบเขตยาวกว่าวงจรที่จะเติม เพิ่มหน่วยความจำเป็นsizeof(long)ชิ้นและในที่สุดไบต์ต่อไบต์จะเต็มพื้นที่ที่เหลือ แม้ว่าตัวจัดสรรจะฉลาดพอที่จะโทรมาบ้างaligned_memsetมันจะยังคงเป็นลูปทั่วไป
หนึ่งข้อยกเว้นที่น่าสังเกตคือเมื่อคุณทำ malloc / calloc ของหน่วยความจำขนาดใหญ่มาก (บาง power_of_two กิโลไบต์) ซึ่งการจัดสรรกรณีอาจทำได้โดยตรงจากเคอร์เนล ในขณะที่เมล็ดในระบบปฏิบัติการโดยทั่วไปจะเป็นศูนย์ออกหน่วยความจำทั้งหมดที่พวกเขาให้ไปด้วยเหตุผลด้านความปลอดภัย calloc ฉลาดพอที่อาจเพียงแค่ส่งกลับมาพร้อมกับ zeroing เพิ่มเติม อีกครั้ง - หากคุณเพิ่งจัดสรรสิ่งที่คุณรู้ว่ามีขนาดเล็กคุณอาจจะดีกว่าด้วยประสิทธิภาพของ malloc + memset
calloc()ช้ากว่าmalloc(): การคูณสำหรับขนาด calloc()จำเป็นต้องใช้การคูณทั่วไป (ถ้าsize_tเป็น 64 บิตแม้การดำเนินการ 64 บิตที่มีราคาแพงมาก * 64 บิต = 64 บิต) ในขณะที่ malloc () มักจะมีค่าคงที่เวลารวบรวม
                    struct foo { char a,b,c; };ไบต์ในช่วงเวลาที่ไม่ได้ไปจะได้เร็วขึ้นเพียงเพราะคุณกำลังแล้วจะใช้การระงับ  callocดีกว่าmalloc+ เสมอmemsetหากคุณจะล้างพื้นที่ทั้งหมดตลอดmallocเวลา  callocมีการตรวจสอบอย่างระมัดระวัง แต่มีประสิทธิภาพสำหรับองค์ประกอบ int * ขนาดที่มากเกินไป
                    ความแตกต่าง 1:
malloc() มักจะจัดสรรบล็อกหน่วยความจำและมันจะเริ่มต้นส่วนหน่วยความจำ
calloc() จัดสรรบล็อกหน่วยความจำและเริ่มต้นบล็อกหน่วยความจำทั้งหมดเป็น 0 
ความแตกต่าง 2:
หากคุณพิจารณาmalloc()ไวยากรณ์มันจะใช้เวลาเพียง 1 อาร์กิวเมนต์ ลองพิจารณาตัวอย่างต่อไปนี้ด้านล่าง:
data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );เช่นหากคุณต้องการจัดสรรหน่วยความจำ 10 บล็อกสำหรับประเภท int
int *ptr = (int *) malloc(sizeof(int) * 10 );หากคุณพิจารณาcalloc()ไวยากรณ์มันจะใช้เวลา 2 ข้อโต้แย้ง ลองพิจารณาตัวอย่างต่อไปนี้ด้านล่าง:
data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));ตัวอย่าง: หากคุณต้องการจัดสรรหน่วยความจำ 10 บล็อกสำหรับประเภท int และกำหนดค่าเริ่มต้นทั้งหมดเป็นศูนย์
int *ptr = (int *) calloc(10, (sizeof(int)));ความคล้ายคลึงกัน:
ทั้งสองmalloc()และcalloc()จะคืนค่าเป็นโมฆะ * โดยค่าเริ่มต้นหากไม่ใช่ประเภท casted!
มีความแตกต่างสองประการ 
 
ข้อแรกคือจำนวนข้อโต้แย้ง malloc()รับอาร์กิวเมนต์เดี่ยว (หน่วยความจำจำเป็นต้องมีหน่วยเป็นไบต์) ในขณะที่calloc()ต้องการสองอาร์กิวเมนต์ 
ประการที่สองmalloc()ไม่เริ่มต้นหน่วยความจำที่จัดสรรในขณะที่calloc()เริ่มต้นหน่วยความจำที่จัดสรรให้เป็นศูนย์
calloc()จัดสรรพื้นที่หน่วยความจำความยาวจะเป็นผลคูณของพารามิเตอร์ callocเติมหน่วยความจำด้วย ZERO's และส่งคืนพอยน์เตอร์ไปที่ไบต์แรก ถ้ามันล้มเหลวในการค้นหาพื้นที่เพียงพอมันจะส่งกลับNULLตัวชี้ไวยากรณ์: ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block);
เช่นptr_var=(type *)calloc(n,s);
malloc()จัดสรรบล็อกหน่วยความจำเดียวขนาด REQUSTED SIZE และส่งกลับพอยน์เตอร์ไปยังไบต์แรก หากไม่สามารถระบุจำนวนหน่วยความจำที่ต้องการได้จะส่งคืนพอยน์เตอร์พอยน์เตอร์ไวยากรณ์: ฟังก์ชั่นใช้เวลาหนึ่งอาร์กิวเมนต์ซึ่งเป็นจำนวนไบต์ที่จะจัดสรรในขณะที่ptr_var=(cast_type *)malloc(Size_in_bytes);malloc()calloc()ฟังก์ชั่นใช้เวลาสองมีปากเสียงหนึ่งเป็นจำนวนขององค์ประกอบและอื่น ๆ ที่เป็นจำนวนไบต์ที่จะจัดสรรสำหรับแต่ละองค์ประกอบเหล่านั้น นอกจากนี้calloc()เริ่มต้นพื้นที่ที่จัดสรรให้เป็นศูนย์ในขณะที่malloc()ไม่ได้
calloc()ฟังก์ชั่นที่มีการประกาศใน<stdlib.h>ส่วนหัวมีคู่ของประโยชน์มากกว่าmalloc()ฟังก์ชั่น
malloc()และcalloc()เป็นฟังก์ชั่นจากไลบรารีมาตรฐาน C ที่อนุญาตการจัดสรรหน่วยความจำแบบไดนามิกซึ่งหมายความว่าทั้งคู่อนุญาตการจัดสรรหน่วยความจำระหว่างรันไทม์
ต้นแบบของพวกเขามีดังนี้:
void *malloc( size_t n);
void *calloc( size_t n, size_t t)มีความแตกต่างสองหลักระหว่างสอง:
พฤติกรรม: malloc()จัดสรรบล็อกหน่วยความจำโดยไม่เริ่มต้นและการอ่านเนื้อหาจากบล็อกนี้จะส่งผลให้มีค่าขยะ calloc()ในทางกลับกันจัดสรรบล็อกหน่วยความจำและเริ่มต้นให้เป็นศูนย์และเห็นได้ชัดว่าการอ่านเนื้อหาของบล็อกนี้จะส่งผลให้ศูนย์
ไวยากรณ์: malloc()รับ 1 อาร์กิวเมนต์ (ขนาดที่จะจัดสรร) และcalloc()รับสองอาร์กิวเมนต์ (จำนวนบล็อกที่จะจัดสรรและขนาดของแต่ละบล็อก)
ค่าส่งคืนจากทั้งคู่เป็นตัวชี้ไปยังบล็อกของหน่วยความจำที่จัดสรรไว้หากประสบความสำเร็จ มิฉะนั้นจะคืนค่า NULLเพื่อระบุว่าการจัดสรรหน่วยความจำล้มเหลว
ตัวอย่าง:
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));ฟังก์ชั่นเดียวกับที่calloc()สามารถทำได้โดยใช้malloc()และ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)); โปรดทราบว่าmalloc()มีการใช้งานมากกว่าcalloc()เนื่องจากเร็วกว่า หากต้องการให้ค่าเริ่มต้นเป็นศูนย์ให้ใช้calloc()แทน
ข้อแตกต่างที่ยังไม่ได้กล่าวถึง: จำกัด ขนาด
void *malloc(size_t size)SIZE_MAXเท่านั้นที่สามารถจัดสรรได้ถึง
void *calloc(size_t nmemb, size_t size);SIZE_MAX*SIZE_MAXสามารถจัดสรรขึ้นประมาณ
ความสามารถนี้ไม่ได้ใช้บ่อยในหลาย ๆ แพลตฟอร์มที่มีการกำหนดแอดเดรสเชิงเส้น ระบบดังกล่าว จำกัดด้วยcalloc()nmemb * size <= SIZE_MAX
พิจารณาประเภทของ 512 ไบต์ที่เรียกว่าdisk_sectorและรหัสต้องการใช้เซ็กเตอร์จำนวนมาก ที่นี่รหัสสามารถใช้งานได้สูงสุดถึงSIZE_MAX/sizeof disk_sectorภาค
size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);พิจารณาสิ่งต่อไปนี้ซึ่งทำให้สามารถจัดสรรได้มากขึ้น
size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);ตอนนี้ถ้าระบบดังกล่าวสามารถจัดหาการจัดสรรขนาดใหญ่เป็นเรื่องอื่น ส่วนใหญ่ในวันนี้จะไม่ ถึงกระนั้นมันก็เกิดขึ้นมาหลายปีแล้วเมื่อSIZE_MAXมีจำนวน 65535 กฎหมายของมัวร์สงสัยว่าสิ่งนี้จะเกิดขึ้นประมาณปี 2030 ด้วยรุ่นหน่วยความจำบางรุ่นSIZE_MAX == 4294967295และพูลหน่วยความจำใน 100 GBytes
size_tมีขนาดใหญ่กว่า 32 บิต คำถามเดียวก็คือว่าการใช้callocกับค่าที่มีผลิตภัณฑ์เกินกว่าSIZE_MAXสามารถพึ่งพาเพื่อให้ผลตอบแทนเป็นศูนย์แทนที่จะส่งกลับตัวชี้ไปยังการจัดสรรที่เล็กลง
                    calloc() SIZE_MAXมันได้เกิดขึ้นในอดีตที่ผ่านมามี 16 บิตsize_tและหน่วยความจำยังคงลดราคาผมเห็นไม่มีเหตุผลมันจะไม่สามารถเกิดขึ้นได้ก้าวไปข้างหน้าถึงแม้ว่ามันจะไม่ได้พบบ่อย 
                    SIZE_MAXจัดสรรขนาดที่มีเกิน แน่นอนว่าไม่จำเป็นต้องมีสถานการณ์ใด ๆ ที่การจัดสรรดังกล่าวอาจประสบความสำเร็จ ฉันไม่แน่ใจว่ามีประโยชน์อย่างใดอย่างหนึ่งจากการบังคับใช้ว่าการใช้งานที่ไม่สามารถจัดการการจัดสรรดังกล่าวจะต้องส่งคืนNULL(โดยเฉพาะอย่างยิ่งเนื่องจากเป็นเรื่องปกติสำหรับการใช้งานบางอย่างที่มีmallocตัวชี้กลับไปยังพื้นที่ที่ยังไม่ได้ตกลง มัน).
                    size_tที่จะuint64_t?
                    จำนวนบล็อก:
 
 malloc () กำหนดบล็อกเดียวของหน่วยความจำที่ร้องขอ
 calloc () กำหนดบล็อกหลายหน่วยความจำที่ร้องขอ
การเริ่มต้น:
 
malloc () - ไม่ชัดเจนและเริ่มต้นหน่วยความจำที่จัดสรร 
calloc () - เริ่มต้นหน่วยความจำที่จัดสรรโดยศูนย์
ความเร็ว:
 
malloc () เร็ว 
calloc () ช้ากว่า malloc ()
อาร์กิวเมนต์และไวยากรณ์:
 
malloc () รับ 1 อาร์กิวเมนต์:  
ไบต์
calloc () รับ 2 อาร์กิวเมนต์:
ความยาว
void *malloc(size_t bytes);         
void *calloc(size_t length, size_t bytes);      ลักษณะของการจัดสรรหน่วยความจำ:
 
ฟังก์ชั่น malloc จะกำหนดหน่วยความจำของ 'ขนาด' ที่ต้องการจากฮีปที่มีอยู่ 
ฟังก์ชัน calloc กำหนดหน่วยความจำที่มีขนาดเท่ากับอะไร 'num * size'
ความหมายเกี่ยวกับชื่อ:
 
ชื่อ malloc หมายถึง "การจัดสรรหน่วยความจำ" 
ชื่อ calloc หมายถึง "การจัดสรรที่ต่อเนื่องกัน"
mallocครอบครัว