คำตอบที่น่าสนใจมากมายสำหรับคำถาม "เก่า" นี้แม้จะมีคำตอบที่ค่อนข้างใหม่ แต่ฉันไม่พบสิ่งใดเลยที่พูดถึงเรื่องนี้ ....
เมื่อนำมาใช้อย่างถูกต้องและมีการดูแลการใช้งานที่สอดคล้องกันของalloca()
(บางทีโปรแกรมประยุกต์กว้าง) เพื่อจัดการการจัดสรรตัวแปรที่มีความยาวขนาดเล็ก (หรือ C99 Vlas ที่สามารถใช้ได้) สามารถนำไปสู่การลดการเจริญเติบโตของสแต็คโดยรวมมากกว่าการใช้งานเทียบเท่ามิฉะนั้นใช้อาร์เรย์ท้องถิ่นขนาดใหญ่ที่มีความยาวคงที่ . ดังนั้นalloca()
อาจดีสำหรับสแต็กของคุณหากคุณใช้อย่างระมัดระวัง
ฉันพบว่าข้อความอ้างอิงใน .... ตกลงฉันทำข้อความนั้นขึ้น แต่ลองคิดดูสิ ....
@j_random_hacker เป็นอย่างมากที่ถูกต้องในการแสดงความคิดเห็นของเขาภายใต้คำตอบอื่น ๆ : การหลีกเลี่ยงการใช้alloca()
ในความโปรดปรานของอาร์เรย์ท้องถิ่นขนาดใหญ่ไม่ได้ทำให้โปรแกรมของคุณปลอดภัยมากขึ้นจากการล้นสแต็ค (ยกเว้นกรณีที่คอมไพเลอร์ของคุณก็พอเก่าที่จะช่วยให้ inlining ของฟังก์ชั่นที่ใช้งานalloca()
ซึ่งในกรณีนี้คุณควร อัปเกรดหรือยกเว้นว่าคุณใช้alloca()
ลูปภายในซึ่งในกรณีนี้คุณไม่ควร ... ใช้alloca()
ลูปภายใน)
ฉันทำงานในสภาพแวดล้อมเดสก์ท็อป / เซิร์ฟเวอร์และระบบฝังตัว ระบบฝังตัวจำนวนมากไม่ใช้ฮีปเลย (เพราะไม่ได้ลิงค์เพื่อสนับสนุน) ด้วยเหตุผลที่รวมถึงการรับรู้ว่าหน่วยความจำที่จัดสรรแบบไดนามิกนั้นเป็นสิ่งที่ไม่ดีเนื่องจากความเสี่ยงของการรั่วไหลของหน่วยความจำในแอพพลิเคชันที่ไม่เคย เคยบูตเครื่องใหม่หลายครั้งในแต่ละปีหรือเหตุผลที่สมเหตุสมผลกว่าที่หน่วยความจำแบบไดนามิกเป็นอันตรายเพราะไม่สามารถทราบได้แน่นอนว่าแอปพลิเคชันจะไม่แยกส่วนฮีปของมันจนถึงจุดที่หน่วยความจำผิดพลาดหมด ดังนั้นโปรแกรมเมอร์ที่ฝังตัวจึงเหลือทางเลือกเล็กน้อย
alloca()
(หรือ VLAs) อาจเป็นเพียงเครื่องมือที่เหมาะสมสำหรับงาน
ฉันได้เห็นเวลาและเวลาอีกครั้งที่โปรแกรมเมอร์สร้างบัฟเฟอร์สแต็กจัดสรร "ใหญ่พอที่จะรองรับกรณีที่เป็นไปได้" ในทรีคอลที่ซ้อนกันอย่างลึกการใช้รูปแบบ (anti -?) ซ้ำ ๆ จะนำไปสู่การใช้สแต็กที่พูดเกินจริง (ลองนึกภาพสายเรียกเข้าลึก 20 ระดับซึ่งแต่ละระดับด้วยเหตุผลที่แตกต่างกันฟังก์ชั่นสุ่มจัดสรรจัดสรรบัฟเฟอร์ที่ 1024 ไบต์ "ตาบอดปลอดภัย" โดยทั่วไปแล้วจะใช้เพียง 16 หรือน้อยกว่าเท่านั้น กรณีที่หายากอาจใช้มากขึ้น) ทางเลือกคือการใช้alloca()
หรือ VLAs และจัดสรรพื้นที่สแต็คให้มากที่สุดเท่าที่ความต้องการของฟังก์ชันของคุณเพื่อหลีกเลี่ยงการสร้างสแต็กโดยไม่จำเป็น หวังว่าเมื่อหนึ่งฟังก์ชันใน call tree ต้องการการจัดสรรที่มีขนาดใหญ่กว่าปกติส่วนอื่น ๆ ใน call tree ยังคงใช้การจัดสรรขนาดเล็กตามปกติและการใช้งานโดยรวมของแอปพลิเคชันโดยรวมนั้นน้อยกว่าอย่างมาก .
แต่ถ้าคุณเลือกที่จะใช้alloca()
...
จากคำตอบอื่น ๆ ในหน้านี้ดูเหมือนว่า VLA ควรจะปลอดภัย (ไม่รวมการจัดสรรสแต็กถ้าเรียกจากภายในลูป) แต่ถ้าคุณใช้alloca()
ระวังอย่าใช้มันในลูปและทำให้แน่ใจว่าฟังก์ชั่นของคุณไม่สามารถอินไลน์ได้หากมีโอกาสที่มันจะถูกเรียกภายในวงของฟังก์ชันอื่น