ฉันควรสอนนักเรียนของฉันให้ดีไหม? [ปิด]


18

วิธีการใช้กันอย่างแพร่หลายallocaในโลกแห่งความจริง? ฉันควรสอนนักเรียนให้ใช้allocaเมื่อเหมาะสมหรือไม่ หรือฉันควรสอนพวกเขาไม่ให้ใช้มัน? มาจากพื้นหลัง C ++ RAII ความคิดที่ว่าคุณไม่จำเป็นต้องโทรหาคนอื่นfreeด้วยตนเองโดยเฉพาะอย่างยิ่งเสียงที่มีแนวโน้ม


ที่เกี่ยวข้อง: stackoverflow.com/questions/1018853/…

8
ทำไมไม่สอนพวกเขาด้วย C99 VLA ล่ะ?

@cnicutar alloca () นั้นขึ้นอยู่กับการใช้งาน แต่อย่างน้อยการใช้งานหลายอย่างกลับ NULL เมื่อล้มเหลว C99 VLA ไม่มีวิธีระบุความล้มเหลว
ดูซับซ้อนใน

2
@sbi: สำหรับคำถามนี้เป็นคำถามปลายเปิดที่ไม่เหมาะกับรูปแบบของสิ่งที่นักคิดคิดว่าควรจะโพสต์ มันเป็นอัตวิสัยเกินไปไม่มีคำตอบที่ชัดเจนเพียงความเห็น ไหนดี แต่ไม่ใช่สำหรับ โปรดสังเกตว่าด้วยความเคารพตัวแทนของ OP ไม่มีใครลงคะแนนเสียงเราเพียงแค่ปิดคำถามนี้เป็นหัวข้อปิด
Paul Sasik

1
@PascalCuoq คุณไม่ควรจัดสรรจำนวนมากกับ alloca / VLA หากไม่แน่ใจว่า "มาก" mallocอยู่ในบริบทปัจจุบันใช้

คำตอบ:


31

หากคุณกำลังเรียนหลักสูตรการเขียนโปรแกรม C ทั่วไปคุณไม่ควรสอนสิ่งที่ไม่ได้มาตรฐาน โปรแกรมเมอร์ระดับเริ่มต้นโดยไม่จำเป็นต้องเขียนโค้ดที่ไม่ได้มาตรฐานและ / หรือไม่พกพาเพราะพวกเขาได้รับการสอนในลักษณะนี้เป็นปัญหาใหญ่สำหรับอุตสาหกรรมซอฟต์แวร์ในช่วง 20-30 ปีที่ผ่านมา ค่าใช้จ่ายสำหรับการไม่สอนพวกเขาถึงมาตรฐานและไม่มีอะไรนอกจากค่ามาตรฐานนั้นน่าจะเป็นดาราศาสตร์

หากคุณกำลังเรียนหลักสูตรขั้นสูงขึ้นในขั้นตอนวิธีหรือการเขียนโปรแกรมประยุกต์อาจเป็นเรื่องดีที่จะกล่าวถึง ในทางกลับกันฉันได้ตั้งโปรแกรมทุกอย่างตั้งแต่แอพฝังตัวแบบเรียลไทม์ไปจนถึงแอพพลิเคชั่น Windows เป็นเวลา 15 ปีโดยที่ไม่เคยใช้ฟังก์ชั่นนั้น


การใช้งานอย่างเดียวที่ฉันเห็นว่ามันไม่ได้ดีไปกว่านี้อีกวิธีหนึ่งคือทำการตรวจจับสแต็กต่อยใน Windows บางเวอร์ชันซึ่งความล้มเหลวในการจัดสรรพื้นที่แสดงให้เห็นว่ามีพื้นที่เหลือไม่เพียงพอ - หรืออาจเป็นเพียง ; มันนานแล้วที่ฉันดูโค้ดนั้น มันใช้งานได้ แต่ก็น่ากลัวนิดหน่อย
Donal Fellows

13

ฉันเห็นสองสิ่งที่เกิดขึ้น:

  1. นักเรียนเข้าใจถึงผลกระทบของallocaอ่านเกี่ยวกับความแตกต่างระหว่างสแต็คและกองและใช้allocaอย่างระมัดระวัง (ไม่น่า)

  2. นักเรียนคิดว่า "ว้าวเป็นแบบนี้mallocโดยไม่ต้องกังวลกับfree" ใช้มันให้มากจนเกินไปให้เกิดการล้นสแต็คและไม่รู้ว่าเกิดอะไรขึ้น

ฉันคิดว่ามันจะดีกว่าถ้าคุณอธิบายallocaแล้วเรียกใช้รหัสนี้:

#include <malloc.h>

int OverflowMyStack(int start) {
    if (start == 0)
        return 0;

    char * p = (char *)_alloca(4096);
    *p = '0';
    return OverflowMyStack(start - 1);
}

int main () {
    return OverflowMyStack(512);
} 

ที่มา: http://www.strchr.com/alloca

แสดงอันตรายให้พวกเขาแล้วบอกพวกเขาว่าอย่าใช้ พวกเขายังคงเรียนรู้เกี่ยวกับสแต็คกับกองดูอันตรายในการดำเนินการและสามารถไปกับสิ่งมาตรฐาน


1
ฉันคิดว่านักเรียนส่วนใหญ่ยังคงอยู่ในหมวดหมู่ที่สองแม้หลังจากแสดงรหัสตัวอย่าง
rightfold

@WTP - อาจเป็นไปได้ แต่นั่นเป็นเหตุผลที่คุณบอกให้ไม่ใช้มันแม้จะแสดงให้พวกเขาเห็นว่าเกิดอะไรขึ้น
BlackJack

4
ทำไมรหัสที่ใช้_allocaมากกว่าalloca? และทำไมมันถึงส่งผล
Keith Thompson

5

คำตอบสำหรับคำถามนี้ควรขึ้นอยู่กับวัตถุประสงค์ของคุณในตอนแรก

คุณต้องการสอนคนที่รู้วิธีเขียนโปรแกรม C และทำงานกับรหัส C ที่มีอยู่ใน wild หรือไม่? ถ้าเป็นเช่นนั้นบอก alloca และสิ่งอื่นที่คุณต้องการ

ในทางตรงกันข้ามถ้าคุณกำลังสอนหลักสูตรเบื้องต้นที่ใช้ C โดยบังเอิญเท่านั้น (และเนื่องจาก C เป็นภาษาที่เล็กมากและอื่น ๆ ) คุณควรเน้นส่วนที่สำคัญ (การเขียนโปรแกรมแบบแยกส่วนรูทีนย่อยคอลเลกชัน .. .) จากมุมมองของนักเรียน alloca เป็นสิ่งที่ซ้ำซ้อนเนื่องจาก malloc นั้นเพียงพอในกรณีส่วนใหญ่และจากมุมมองโค้ดที่ดีคุณจะดีกว่าอย่างชัดเจนเมื่อพูดถึงการจัดการหน่วยความจำด้วยตนเองเป็นที่น่ารำคาญและภาษาอื่น ๆจัดการกับปัญหานี้อย่างไร สิ่งต่าง ๆ เพื่อการจัดการหน่วยความจำแล้ว alloca หรือ RAII ดังนั้นคุณไม่ควร จำกัด ตัวเองกับสิ่งเหล่านี้และอย่างที่คุณได้พูดไปแล้วมันง่ายกว่ามากที่จะเข้าใจวัตถุประสงค์ของ alloca ถ้าคุณเปรียบเทียบกับวิธีอื่น ๆ (หรือ C99 ... )


2

เลขที่

เหตุผลเดียวที่โปรแกรมเมอร์ C ควรตระหนักถึงการมีอยู่ของ alloca คือการเข้าใจและแก้ไขรหัสดั้งเดิมที่ใช้งาน

การใช้งานใด ๆ ก็ได้allocaเช่นกัน

  1. ไร้ประโยชน์นั่นคือมันอาจถูกแทนที่ด้วยตัวแปรขนาดคงที่ของระยะเวลาการจัดเก็บอัตโนมัติหรือ
  2. กองล้นที่อันตรายกำลังรอให้เกิดขึ้น

นอกเหนือจากการทดลองทางความคิดที่ฉันไม่เคยพบตัวอย่างในโลกแห่งความจริงแล้วยังไม่มีกรณีการใช้งานสำหรับalloca(หรือ VLA) ที่ไม่ไร้ประโยชน์หรือมีช่องโหว่ (หนึ่งใน 2 กรณีข้างต้น)


2
แน่นอนว่าไม่มีใครสามารถใช้มันอย่างรับผิดชอบ ไม่ไม่เคย.
DeadMG

การใช้ "รับผิดชอบ" เพียงอย่างเดียวallocคือ 100% เทียบเท่ากับอาร์เรย์อัตโนมัติขนาดคงที่และเคลื่อนย้ายได้น้อยลง
. GitHub หยุดช่วยน้ำแข็ง

ฉันเดาว่าไม่มีใครต้องการจัดสรรจำนวนไดนามิกบางอย่างพูดสักสองสามกิโลไบต์ซึ่งจะไม่มีวันล้น หรือเรียกใช้ฟังก์ชั่น OS API บางอย่างซึ่งจะแจ้งให้ทราบว่ามีให้บริการเท่าใด หรือเพียงเพิ่มขนาดสแต็คเป็นจำนวนมาก
DeadMG

หากเป็นไม่กี่ KB และคุณมั่นใจว่าคุณมี KB ไม่กี่คุณสามารถใช้T foo[5000];หรืออะไรก็ได้
.. GitHub หยุดช่วยเหลือน้ำแข็ง

เฉพาะในกรณีที่ T มีคอนสตรัคค่าเริ่มต้นเล็กน้อย ถ้าฉันเป็นคนที่ต้องการประสิทธิภาพการทำงานแม้กระทั่งความทรงจำที่เป็นศูนย์ธรรมดาก็อาจทำให้ฉันเสีย แต่ประเภทอื่น ๆ อาจมีตรรกะการก่อสร้างเริ่มต้นที่ซับซ้อนยิ่งขึ้น ตัวอย่างเช่นถ้าฉันต้องการสร้างอาร์เรย์แบบไดนามิกstd::mutexฉันอาจเรียกใช้การเรียกเคอร์เนลและการสลับบริบทสำหรับ 5,000 mutexes ไม่ถูก. ไม่ต้องพูดถึงต้นทุนแคชเพิ่มเติมของการวางตัวแปรท้องถิ่นหลังจากอาร์เรย์
DeadMG

1

ความคิดเห็นของฉันไม่สนับสนุนให้ใช้เว้นแต่คุณจะสอนหลักการคอมไพเลอร์ระดับต่ำที่ใช้ในการจัดสรรพื้นที่สแต็กสำหรับตัวแปรท้องถิ่น สอนในบริบทนั้น


0

เอกสาร GCCalloca()มีข้อดีปฏิบัติคู่และข้อเสียใน จากมุมมองที่ใช้งานได้จริงซอฟต์แวร์เสรีจำนวนหนึ่งใช้ดังนั้นจึงเป็นเรื่องดีที่จะเข้าใจวิธีการทำงานและตำแหน่งที่ใช้ในโค้ดที่มีอยู่

ผ่าน -Wl,-stack=ขนาดสแต็กใหม่ไปยัง gcc จะเพิ่มขนาดสแต็กสูงสุด คุณจะต้องทำสิ่งนี้หากโครงการของคุณใช้alloca()หรือจัดสรรอาร์เรย์ชั่วคราวขนาดใหญ่หรือใช้การเรียกซ้ำผ่านความลึกตามบริบทที่กำหนด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.