ตัวจัดสรรหน่วยความจำ

ความต้องการ

คลาส (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 เช่นกัน

การใช้งาน

เมื่อมีการอินแสตนท์คอนเทนเนอร์มาตราฐานของตัวจัดการหน่วยความจำผ่านทางเทมเพลตอาร์กิวเมนต์ ด้วยค่าเริ่มต้น 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) ของลิสท์ ของเซต ของประเภทข้อมูลที่ถูกกำหนดโดยผู้ใช้, สามารถมั่นใจว่าหน่วยความจำทั้งหมดได้มาจากคอนเทนเนอร์ของตัวจัดสรรหน่วยความจำ