ในการเขียนโปรแกรมคอมพิวเตอร์ภาษาซีพลัสพลัส, **allocators** หรือ ตัวจัดสรรหน่วยความจำ เป็นคอมโพเนนท์ที่สำคัญใน ไลบรารี่มาตราฐานของ C++ ซึ่งได้กำหนด โครงสร้างข้อมูลหลายตัว อย่างเช่น ลิสต์ (List) หรือ รายการ, เซต (Set) โดยทั่วไปโครงสร้างข้อมูลเหล่านี้รู้จักกันในนาม คอนเทนเนอร์ (Container) ลักษณะโดยทั่วไปของคอนเทนเนอร์คือ ความสามารถที่เปลี่ยนขนาดการจองหน่วยความจำได้ในขณะที่โปรแกรมกำลังทำงาน เพื่อที่จะสามารถกระทำการทำงานเหล่านี้ได้มีความจำเป็นอย่างยิ่งที่ต้องใช้ การจัดสรรหน่วยความจำแบบพลวัต (Dynamic memory allocation) โดยการจัดสรรหน่วยความจำจะจัดการคำร้องขอการจัดสรร (allocation) และยกเลิการจัดสรร (deallocation) หน่วยความจำ ทั้งหมดแก่คอนเทนเนอร์ ไลบรารี่มาตราฐานของ C++ กำหนดให้ รูปแบบการจัดสรรหน่วยความเบื้องต้นให้แก่ผู้ใช้งานตั้งแต่เริ่มต้น อย่างไรก็ตามการปรับแต่งการจัดสรรหน่วยความจำ (Custom allocator) เพิ่มเติมก็สามารถทำได้ด้วยผู้พัฒนาโปรแกรม

ตัวจัดการหน่วยความจำ ที่เป็นส่วนหนึ่งของ Standard Template Library (STL) ถูกคิดค้นโดย Alexader Stepanov พวกเขาเริ่มต้นการคิดค้นเพื่อที่สร้างไลบรารี่ที่สามารถยืดหยุ่น และเป็นอิสระกับแบบจำลองหน่วยความจำระดับล่าง (Underlying memory model) ที่อนุญาตให้ผู้พัฒนาโปรแกรมใช้ตัวชืี้ที่กำหนดเอง (Custom pointer) และ การอ้างถึง ประเภทข้อมูลในไลบรารี่ อย่างไรก็ตามในขั้นตอนของการปรับ STL เข้ากับมาตราฐานของ C++ คณะกรรมการวางมาตราฐาน C++ (C++ standardiaztion committee) ได้ตระหนักถึง การทำแบบจำลองหน่วยความจำในแบบแอ็บสแตรค (Abstraction of the memory model) ทั้งหมด จะส่งผลเสียอย่างมากต่อประสิทธิภาพ จนไม่สามารถยอมรับได้ เพื่อที่จะแก้ไขปัญหานี้ ข้อกำหนดของตัวจัดสรรหน่วยความจำจึงถูกสร้างให้มีข้อจำกัดมากขึ้น ส่งผลให้ ระดับปรับปรุงแก้ใขที่ถูกกำหนดด้วยตัวจัดการหน่วยความจำมีข้อจำกัดกว่าในตอนที่เริ่มต้นในแนวคิดของ Stepanov

แม้กระนั้น ยังคงมีหลายๆ สถานการที่มีความจำเป็นในการปรับปรุงตัวจัดการหน่วยความจำ และในหลายๆเหตุผลในการปรับแต่งตัวจัดการหน่วยความจำนั้น ก็เพื่อเพิ่มประสิทธิ์ภาพในการจัดสรรหน่วยความจำ ให้ใช้หน่วยความจำแบบพูล (Memory pools) และการเอนแคบซูเลท (Encapsulating) การเข้าถึงของประเภทหน่วยความจำหลายชนิด อย่างเช่น หน่วยความจำที่ใช้ร่วมกัน (Shared memory) และ การกำจัดหน่วยความจำที่ไม่ใช้ (Garbage collected memory) โดยเฉพาะอย่างยิ่งโปรแกรมที่ใช้หน่วยความจำขนาดเล็กบ่อยๆ จะได้รับประโยชน์จากการปรับปรุงตัวจัดสรรหน่วยความจำ ทั้งในแง่ของ การทำงานของโปรแกรม และขนาดของการใช้งานหน่วยความจำ

ประวัติ
-------

ข้อมูลเพิ่มเติม : Standard Template Library

Alexander Stepanov และ Meng Lee นำเสนอ Standard Template Library (STL) แด่คณะกรรมการวางมาตราฐาน C++ (C++ standardiaztion committee) ใน เดือนมีนาคม 2537 แม้ว่าจะประสพปัญหาบ้างแต่ไลบราลี่ก็ได้รับการอนุมัติในเบื้องต้น โดยเฉพาะอย่างยิ่ง Stepanov ได้ถูกร้องขอให้ทำการสร้างไลบรารี่ของคอนเทนเนอร์ ที่เป็นอิสระจากแบบจำลองหน่วยความจำระดับล่าง ซึ่งนำไปสู่การสร้างตัวจัดสรรหน่วยความจำ และในเวลาต่อมา อินเทอร์เฟสของ STL คอนเทนเนอร์ได้ถูกเขียนขึ้นใหม่ เพื่อที่จะสามารถใช้ตัวจัดสรรหน่วยความจำได้

ในการปรับปรุง STL ให้ถูกบรรจุในไลบรารี่มาตราฐานของ C++ Stepanov ได้ทำงานอย่างใกล้ชิดกับสมาชิกในกรรมการวางมาตราฐานบางท่าน ซึ่งประกอบด้วย Andrew Koenig และ Bjarne Stroustrup ซึ่งเป็นคนสังเกตว่า การปรับแต่งตัวจัดสรรหน่วยความจำมีความเป็นไปอย่างมากที่จะดำเนินการในการจัดเก็บ STL คอนเทนเนอร์อย่างถาวร ซึ่งขณะนั้น Stepanov กำลังพิจารณา "important and interesting insight" "ส่วนที่สำคัญและ หน้าสนใจ"

|  |
| --- |
| จากมุมมองความสามารถในการโอนย้าย ของอุปกรณ์ที่ถูกกำหนดที่เกี่ยวข้องกับการกล่าวถึง แอดเดรส (Address) พอร์ยเตอร์ (Pointer) และอื่นๆ จะถูกเอนแคปซูเลตไว้ในหน่วยความจำที่มีขนาดเล็กและทำงานอย่างตรงไปตรงมา
—Alex Stepanov, นักออกแบบของ the Standard Template Library |

ในตอนเริ่มต้นข้อเสนอของตัวจัดสรรหน่วยความจำไม่สามารถทำงานร่วมในการใช้งานบางกรณี ที่ยังไม่เป็นที่ยอมรับจากคณะกรรมการวางมาตราฐาน คือความสามารถของการกำหนดชื่อที่ใช้ใน เทมเพลตอาร์กิวเมนต์ (Templat argument) เป็นเทมเพลตของตัวมัน ตั้งแต่ฟีเจอร์ (Feature) แบบนั้นไม่สามารถถูกคอมไพล์ (Compile) ได้ในทุกคอมไพเลอร์ (Compiler) ที่มีในตอนนั้น ตามคำกล่าวของ Stepanov ว่า "ทำให้ Bjarne [Stroustrup] และ Andy [Koenig] ใช้เวลาอย่างมากในการที่ จะพยายามตรวจสอบว่าพวกเราได้ทำการพัฒนาอย่างถูกต้องหรือไม่ กับฟีเจอร์ที่ไม่สามารถใช้งานได้" ทำให้ไลบรารี่ที่เคยให้งานพอร์ยเตอร์ และ เรฟเฟอร์เรนซ์ไทป์โดยตรง ถูกเปลี่ยนมาใช้การอ้างถึง ไทป์โดยตัวจัดสรรหน่วยความจำแทน Stepanov ได้กล่าวถึงตัวจัดสรรหน่วยความจำในตอนหลังว่า "ข้อดีของฟีเจอร์ใน STLคือ การเจาะจงที่จะสนใจแต่ประเภทข้อมูลที่มีขึ้นกับอุปกรณ์(...) ซึ่งถูกเอนแคบซูเลท (Encapsulated) ภายในโค้ดราวๆ 16 บรรทัด"

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

ต่อมา Stepanov ได้ให้ความเห็นว่า ในเมือตัวจัดสรรหน่วยความจำ "ไม่ได้เป็นสิ่งที่เลวร้ายใน [แนวคิด] ทางทฤษฏี(...) โชค(ไม่) ดีพวกมัน ไม่สามารถทำได้ในทางปฏิบัติ" เขาสังเกตว่าเพื่อที่จะให้ตัวจัดสรรหน่วยความจำมีประโยชน์อย่างจริงจัง การปรับเปลี่ยน แกนหลักของภาษา (C++) นั้นเป็นสิ่งจำเป็น

ในการปรับปรุงมาตราฐานของ C++ ในปี 2554 ได้ยกเลิกคำสั่งที่ทำให้สับสนของตัวจัดการหน่วยความจำที่ให้ถูกเปรียบเที่ยบกับค่าเท่ากับ และ ถูกใช้เป็นพอร์ยเตอร์ โดยการเปลี่ยนแปลงนี้ทำให้ตัวจัดสรรหน่วยความจำที่เป็น สเตทฟูล (Stateful) สามารถใช้งานได้มากขึ้น และยอมให้ตัวจัดการหน่วยความจำสามารถจัดการ หน่วยความจำร่วมกันที่ไม่อยู่ในโพรเซส (out-of-process shared memory) ได้ จุดประสงค์ของตัวจัดสรรหน่วยความจำในตอนนี้คือเพื่อให้คนเขียนโปรแกรมสามารถควบคุมหน่วยความจำที่อยู่นอกเหนือกับที่ถูกจัดสรรในคอนเทนเนอร์ และแทนที่จะเป็นการปรับแบบจำลองแอดเดรส (Address model) ที่อยู่ภายใต้ส่วนของฮาร์ดแวร์ (Hardware) ในความเป็นจริงการปรับปรุงมาตราฐานได้ยกเลิกความสามารถของตัวจัดสรรหน่วยความจำที่แสดงถึงการขยายไปยัง แบบจำลองแอดเดรสของ C++ (C++ address model) โดยทั่วไป (และจงใจ) ยกเลิกจุดประสงค์ตั้งแต่เริ่มแรกในการทำตัวจัดสรรหน่วยความจำ

ความต้องการ
-----------

คลาส (Class)ใดๆที่เติมเต็มสามารถตัวจัดสรรหน่วยสามารถเป็นเสมือนตัวจัดสรรหน่วยความจำ โดยเฉพาะอย่างยิ่ง คลาสที่สามารถจัดสรรหน่วยความจำสำหรับอ็อปเจ็ค (Object) ไทป์ `T` ที่ต้องกำหนดประเภทข้อมูล `A::pointer, A:const_pointer, A::reference, A::const_reference และ A::value_type` สำหรับการประกาศอ็อปเจ็คทั่วไป และการอ้างอิง​ (หรือพอร์ยเตอร์) ไปยังอ็อปเจ็คไทป์ `T` ซึ่งควรที่จะให้ ไทป์ `A::size_type` เป็นข้อมูลประเภทไม่มีสัญญาลักษณ์ที่สามารถรองรับการแสดงข้อมูลขนาดที่ใหญ่ที่สุดของอ็อปเจ็ค A ที่ถูกกำหนดในแบบจำลองตัวจัดสรรหน่วยความจำได้ และคล้ายกับสัญญาลักษณ์ใน `A:difference_type` ที่สามารถแสดงความแตกต่างระหว่างพอร์ยเตอร์สองตัวในตัวจัดสรรหน่วยความจำ

แม้ว่าความสอดคล้องในการทำไลบรารี่มาตราฐานที่อนุญาตที่จะอ้างถึง `A:pointer` และ `A::const_pointer` ของตัวจัดสรรหน่วยความจำเป็น ไทป์เด็ฟส์ (Typedefs) สำหรับ `T*` และ `T const*,`  ไลบรารี่ยังสนับสนุนตัวจัดสรรหน่วยความจำตัวที่เป็น เจนเนอร์รอลไทป์ (General type) ตัวอื่นๆด้วย

ตัวจัดสรรหน่วยความจำ (ในที่นี้ขอกำหนดเป็น `A`) สำหรับอ็อปเจ็คประเภท `T` จะต้องมีฟังก์ชัน (Function) ที่มีซิกเนเจอร์ (Signature) หรือรูปแบบของอาร์กิวเมนต์(Argrument) ในการเรียกใช้งานฟังก์ชัน ด้วย `A::pointer A::allocate (size_type n, A<void>::const_pointer hint = 0)` ฟังก์ชันนี้จะทำการคืนค่าพอร์ยเตอร์ที่ชี้ไปยังอิลิเมนต์ (Element) ตัวแรกของอาเรย์ที่ถูกจัดสรรที่มีขนาดใหญ่พอที่จะรองรับอ็อปเจ็ค n จำนวนที่เป็นไทป์ `T` หน่วยความจำเท่านั้นที่ถูกทำการจอง และอ็อปเจ็คยังไม่ได้เกิดการสร้างขึ้นและมากไปกว่านั้น ตัวเลือกพอร์ยเตอร์อาร์กิวเมนต์ (ที่ชี้ไปยังอ็อปเจ็คที่ได้จับจองไว้แล้วด้วย A) สามารถถูกใช้เหมือนการแนะนำเพื่อที่จะดำเนินการเกี่ยวกับที่ของหน่วยความจำใหม่ที่ควรจะจัดสรรตามลำดับเพื่อปรับปรุงหน่วยความจำที่ถูกจอง อย่างไรก็ตามการดำเนินการก็สามารถที่จะละอากิวเมนต์ได้

การสอดคล้องของ `void A::deallocate(A::pointer p, A::size_type n) สมาชิกของ`ฟังก์ชันจะยอมรับพอร์ยเตอร์ตัวใดก็ได้ที่สามารถคืนค่าจากการเรืยกใช้ของสามาชิกของฟังก์ชัน `A::allocate` ก่อนหน้าและจำนวนอิลิเมนต์ที่ถูกยกเลิกการจัดสรร (Deallocate) แต่ไม่ได้ถูกทำลาย (Destruct)

`A::max_size()` เป็นฟังก์ชันที่คืนค่าเป็นจำนวนตัวเลขที่มากพอของอ็อปเจ็คไทป์ `T` ที่คาดว่าจะถูกทำการจัดสรรสำเร็จด้วยการเรียกใช้ `A::allocate` โดยค่าที่คืนกลับจะเป็น `A::size_type(-1) / sizeof (T)`ดังนั้น สมาชิกของฟังก์ชัน `A::address` จะคืน `A::pointer` ที่ชี้ไปยังแอดเดรสของอ็อปเจ็ค และให้ `A:reference` ของอ็อปเจ็ค

อ็อปเจ็คที่ถูกสร้าง (Construct) และถูกทำลาย (Deconstruct) จะถูกจัดการแยกต่างหากจาก ​การจัดสรร (Allocation) และยกเลิกการจัดสรร (Deallocation) หน่วยความจำ ส่วนตัวจัดสรรหน่วยความจำจะต้องการฟังก์ชัน 2 ตัวคือ `A::constuct` และ ​`A::destroy` เพื่อที่จะรองรับอ็อปเจ็คที่ถูกสร้างและถูกทำลายตามลำดับ โดยความหมายของฟังก์ชันควรที่จะเทียบเท่ากับเนื้อความข้างล่างนี้

```
template <typename T>
void A::construct(A::pointer p, A::const_reference t) { new ((void*) p) T(t); }
 
template <typename T>
void A::destroy(A::pointer p){ ((T*)p)->~T(); }
```

โค้ดโปรแกรมข้างบนนี้จะใช้ไวยากรณ์ (Syntax) `new` และเรียก destructor ตรงๆ

ตัวจัดสรรหน่วยความจำควรจะทำการสำเนาการสร้าง (Copy-constructible) : ตัวจัดสรรหน่วยความจำของอ็อปเจ็คไทป์ `T` สามารถที่จะถูกสร้างจากตัวจัดสรรหน่วยความของอ็อปเจ็คไทป์ `U` ถ้าตัวจัดสรรหน่วยความจำ (`A`) จัดสรรหน่วยความจำที่บริเวณหน่วยความจำ `R` แล้ว `R` สามารถถูกยกเลิกการจัดสรรได้ก็ต่อเมื่อเป็นตัวจัดสรรหน่วยความจำที่เทียบได้กับ `A` เท่านั้น

ตัวจัดสรรหน่วยความจำยังต้องการได้รับเทมเพลตคลาส `template <typename U> struct A::rebind { typedef A<U> other; };` ที่ยินยอมให้อ้างอิงถึงตัวจัดสรรหน่วยความจำ, พารามิเตอร์ในรูปแบบชนิดอื่น ตัวอย่างเช่น การให้ตัวจัดสรรหน่วยความจำ ไทป์ `IntAllocator` แก่อ็อปเจ็คประเภท `int` ความสัมพันธ์ของตัวจัดสรรหน่วยความจำกับประเภทข้อมูล `long` ก็ควรจะได้รับเมื่อมีการใช้ `IntAllocator::rebind<long>::other` เช่นกัน

การปรับแต่งตัวจัดสรรหน่วยความจำ
-------------------------------

ประสิทธิภาพเป็นเหตุผลหลักเหตุอันหนึ่งที่ทำให้ต้องมีการปรับแต่งตัวจัดหน่วยความจำ การใช้ตัวจัดสรรหน่วยความจำที่พิเศษในการเพิ่มประสิทธิ์ภาพ หรือการลดจำนวนการใช้งานหน่วยความจำ หรือทั้งสองอย่าง[4] โดยเริ่มต้นตัวจัดสรรหน่วยความจำจะใช้โอเปอเรเตอร์ (Operator) `new` ในการจองหน่วยความจำ และบ่อยครั้งที่มีการใช้เป็นเลเยอร์ครอบฟังก์ชันตัวจัดสรรหน่วยความจำแบบฮีป (Heap) ที่จัดการอย่างเหมาะสมกับบล็อคขนาดใหญ่ของหน่วยความจำที่ใช้นานๆครั้งในโปรแกรม ในการใช้งานนี้อาจจะถูกใช้ได้ดีกับคอนเทนเนอร์ขนาดใหญ่ที่จองในหน่วยความจำอย่าง เวคเตอร์ (vector) และ เด็ค (deque - double-ended queue) อย่างไรก็ตามสำหรับคอนเทนเนอร์ที่จำเป็นต้องใช้การจัดสรรสำหรับอ็อปเจ็คขนาดเล็กที่มีลำดับ อย่างเช่น แมค (Map) และ ลิสท์ (list) โดยใช้ตัวจัดสรรหน่วยความจำพื้นฐานจะช้า ปัญหาอื่นที่พบบ่อยอย่าง ตัวจัดสรรหน่วยความจำ malloc (malloc-based allocator) ที่ใช้ร่วมกับการอ้างถึงหน่วยความจำเฉพาะที่ (locality of reference) ที่ไม่เหมาะสม และการกระจัดกระจายของหน่วยความจำ (memory fragmentation) ที่มากเกินไป 

|  |
| --- |
| โดยย่อ, ในวรรคนี้ (...) คือ มาตราฐานที่ "ผมฝันไว้" ที่กล่าวถึงตัวจัดสรรหน่วยความจำ จนกว่าความฝันเป็นจริง นักพัฒนาโปรแกรมจะต้องสนใจเกี่ยวกับการการโอนย้ายโปรแกรมจะถูกจำกัดที่ตัวของโปรแกรมที่ทำการปรับแต่งตัวจัดสรรหน่วยความจำโดยไม่มีสถานะ (State)
—Scott Meyers, *Effective STL* |

วิธีที่นิยมในการปรับปรุงประสิทธิ์ภาพการทำงานคือ การสร้างตัวจัดสรรหน่วยความจำแบบพูล แทนที่จะทำการจองหน่วยความจำในทุกครั้งที่มีการเพิ่มไอเทม หรือการเอาไอเทมออกจากคอนเทนเนอร์ การจองหน่วยความจำขนาดใหญ่ (หน่วยความจำแบบพูล) ไว้ล่วงหน้า หรือถ้าเป็นไปได้ตอนเริ่มเปิดโปรแกรม การตัวจัดสรรหน่วยความจำที่ถูกปรับแต่งจะรองรับการร้องขอการจองหน่วยความจำโดยการคืนค่าของพอร์ยเตอร์ที่ชี้ไปยังหน่วยความจำแบบพูล (Pool memory) จริงๆแล้วการคืนหน่วยความจำสามารถเลือนการทำงานได้จนกว่าจะไม่มีความจำเป็นในการใช้งานหน่วยความจำแบบพูล หรือ อาจกล่าวได้ว่าอายุของหน่วยความจำพูลได้สิ้นสุดลง ตัวอย่างของตัวจัดสรรหน่วยความจำแบบพูลสามารถที่พบได้ในไลบรารี่ Boost ใน C++

หัวข้อการปรับแต่งตัวจัดการหน่วยความจำได้ถูกแก้ไขโดยผู้เชี่ยวขาญ C++ และนักเขียนโปรแกรมหลายต่อหลายคน รวมถึง Scott Meyers จาก *Effective STL* และ ​Andrei Alexandrescu จาก *Modern C++ Design.* Mayers สังเกตว่า ความต้องการสำหรับอินสแตนซ์จากตัวจัดสรรหน่วยความจำมีผลเทียบเท่ากับ ผลกระทบที่ได้รับของการโอนย้ายตัวจัดสรรหน่วยความจำไปยังการไม่มีสถานะ แม้ว่าในมาตราฐานของ C++ จะแสดงถึงไลบรารี่ให้การสนับสนุนตัวจัดสรรหน่วยความจำแบบมีสถานะ (Stateful), Meyers เรียกข้อความวรรคนี้ว่า "a lovely sentiment" that "offers you next to nothing", characterizing the restriction as "draconian"

ในภาษา C++ ของ Bjarne Stroustrup หรืออีกนัยหนึ่งระบุถึง การแสดงการควบคุมอย่างเข้มงวดต่อข้อมูลแต่ล่ะอ็อปเจ็คในตัวจัดสรรหน่วยความจำไม่ได้รุนแรงนัก และชี้ให้เห็นว่าตัวจัดสรรหน่วยความจำส่วนใหญ่ไม่จำเป็นต้องมีสถานะ และจะมีประสิทธิภาพที่ดีขึ้นถ้าไม่มีสถานะ เขากล่าวถึงในกรณี การปรับแต่งตัวจัดสรรหน่วยความจำ(custom allocators), การตั้งชื่อ (Namely), ตัวจัดสรรหน่วยความจำแบบพูล (memory pool allocators), หน่วยความจำแบบแชร์ (shared memory allocators) และตัวกำจัดหน่วยความจำที่ไม่ใช (Garbage collected memory allocator) ซึ่งเขาได้แสดงให้เห็นถึงการดำเนินการสร้างตัวจัดการหน่วยความจำ ที่ใช้หน่วยความจำภายในแบบพูล (internal memory pool) สำหรับการจัดสรรหน่วยความจำอย่างรวดเร็ว และการยกเลิกหน่วยความจำขนาดเล็ก แต่ตั้งข้อสังเกตุว่าการดำเนินการที่เหมาะสมอาจจะถูกกระทำโดยตัวจัดสรรหน่วยความจำที่ถูกอิมพลิเมนท์ (Implementation)แล้ว

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

### การใช้งาน

เมื่อมีการอินแสตนท์คอนเทนเนอร์มาตราฐานของตัวจัดการหน่วยความจำผ่านทางเทมเพลตอาร์กิวเมนต์ ด้วยค่าเริ่มต้น `std::allocator<T>;`

```
namespace std {
  template <class T, class Allocator = allocator<T> > class vector;
// ...
```

เหมือนกับทุกๆ C++ คลาสเทมเพลต การอินแสตนท์ของคอนเทนเนอร์ไลบรารีมาตราฐาน จะใช้ความแตกต่างอาร์กิวเมนต์ของตัวจัดสรรหน่วยความจำเป็นตัวแยกแยะประเภทข้อมูล ฟังก์ชันที่คาดว่าจะใช้คืออาร์กิวเมนต์ของ `std::vector<int>` ซึ่งจะยอมรับแต่เวคเตอร์ (`vector`) ของอินแสตนท์ที่เป็นตัวเริ่มต้นของตัวจัดสรรหน่วยความจำ

### การปรับปรุงตัวจัดสรรหน่วยความจำใน C++ 11

ในมาตราฐานของ C++ ล่าสุดได้ปรับปรุงตัวจัดสรรหน่วยความจำให้สามารถยอมรับ "ขอบเขต" (scope) ของตัวจัดสรรหน่วยความจำ และคอนเทเนอร์ที่ประกอบด้วยการจัดสรรหน่วยความจำที่ซ้อนกัน (Nested) เช่น เวคเตอร์ของสตริง หรือ แมพ (map) ของลิสท์ ของเซต ของประเภทข้อมูลที่ถูกกำหนดโดยผู้ใช้, สามารถมั่นใจว่าหน่วยความจำทั้งหมดได้มาจากคอนเทนเนอร์ของตัวจัดสรรหน่วยความจำ

อ้างอิง
-------

1. ↑  Stepanov,
Alexander; Meng Lee (7 March 1994). "The Standard Template Library.
Presentation to the C++ standards committee". Hewlett Packard
Libraries. Retrieved 12 May 2009.
2. 1 2 3  Stevens,
Al (1995). "Al Stevens Interviews Alex Stepanov". *Dr Dobb's Journal*. Archived from
the original on 1 May 2009. Retrieved 12 May 2009.
3. 1 2 3  Stroustrup,
Bjarne (1997). *The C++ Programming Language, 3rd edition*. Addison-Wesley.
4. 1 2 3 4 5 6  Meyers, Scott (2001). *Effective STL: 50 Specific*
Ways to Improve Your Use of the Standard Template Library*. Addison-Wesley.*
5. ↑  Lo Russo, Graziano (1997). "An Interview with A. Stepanov". www.stlport.org. Retrieved 13 May 2009.
6. ↑  Halpern,
Pablo (4 February 2008). "Allocator-specific Swap and Move
Behavior". *ISO*.
Retrieved 21 August 2012.
7. ↑  Halpern,
Pablo (22 October 2009). "Allocators post Removal of C++ Concepts
(Rev 1)". *ISO*.
Retrieved 21 August 2012.
8. ↑  Becker,
Pete. "LWG Issue 1318: N2982 removes previous allocator capabilities (closed in March, 2011)". *ISO*. Retrieved 21 August 2012.
9. 1 2 3  ISO/IEC (2003). *ISO/IEC 14882:2003(E): Programming Languages - C++§20.1.5 Allocator requirements*
10. 1 2  ISO/IEC (2003). *ISO/IEC 14882:2003(E): Programming Languages - C++§20.1.5 Allocator requirements [lib.allocator.requirements]* para. 5
11. ↑  Langer, Angelika; Klaus Kreft (1998). "Allocator Types". *C++ Report*. Retrieved 13
May 2009.
12. 1 2 3  Austern, Matthew (1 December 2000). "The Standard Librarian: What Are Allocators Good For?". *Dr. Dobb's Journal*. Archived from the original on 28 April 2009. Retrieved 12 May 2009.
13. 1 2 3 4  Aue,
Anthony (1 September 2005). "Improving Performance with Custom Pool Allocators for STL". *Dr Dobb's Journal*. Retrieved 13 May 2009.
14. ↑  ISO/IEC (2003). *ISO/IEC 14882:2003(E): Programming Languages - C++§20.4.1.1 allocator members [lib.allocator.members]* para. 3
15. 1 2 3  Alexandrescu, Andrei (2001). *Modern C++ Design*. Addison-Wesley. p. 352.ISBN 0-201-70431-5.
16. ↑  Vlasceanu, Christian (1 April 2001). "Debugging Memory Errors with Custom Allocators". *Dr Dobb's Journal*. Retrieved 14 May 2009.
17. 1 2  Austern,
Matthew (1 December 2001). "The Standard Librarian: A Debugging Allocator". *Dr Dobb's Journal*. Retrieved 14 May 2009.
18. ↑  ISO/IEC (2003). *ISO/IEC 14882:2003(E): Programming Languages - C++ §23.2 Sequences [lib.sequences]* para. 1
19. ↑  Halpern, Pablo (29 February 2008). "The Scoped Allocator Model (Rev 2)".*ISO*. Retrieved 21 August 2012.

แหล่งข้อมูลอื่น
---------------

* CodeGuru Allocators (STL).
* An introductory article "C++ Standard Allocator, An Introduction and Implementation".
* A custom allocator implementation based on malloc