الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

حجز و تحرير الذاكره و الفيجوال ستديو

بدأه C++er في 20 مارس 2010 · 2 رد · 490 مشاهدة · في لغة C و ++C
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

داخل لغة الـ C يتم حجز و تحرير الذاكره بإستخدام malloc و realloc و free، اما داخل الـ Cpp فيتم حجز و تحرير الذاكره بإستخدام new و delete للكائنات و new[] و delete[] للمصفوفات.

جميع الداول السابقه داخل نظام تشغيل ويندوز تقوم بإستدعاء HeapAlloc و HeapReAlloc و HeapFree و هم ما اقوم بإستخدامهم داخل برامجى.

الدوال السابقه (فى السطر السابق فقط) تطلب منك الـ Heap الذى تريد اجراء العمليات داخله سواء كانت حجز او تحجيم او تحرير و يتم تمرير لها GetProcessHeap.

المشكله تحدث عندما اقوم داخل الدوال التى اصنعها بإستخدام GetProcessHeap حيث ان الفيجوال ستديو لا يستخدم الـ Heap الإفتراضى للـ Process قيد الإنشاء و انما يستخدم واحد اخر لأغراض الـ Debug و بالتالى داخل الكود و اثناء عمل البرنامج داخل الفيجوال ستديو لا يمكن استدعاء delete لذاكره تم حجزها بإستخدام HeapAlloc حيث ان delete تقوم بالحذف من داخل الـ Debug Heap الخاص بالفيجوال ستديو و بالتالى يتوقف عمل البرنامج و يظهر exception لمحاولة تحرير ذاكره ليست ملكى، فى حين انه عند عمل البرنامج داخل مساحة ذاكرته الخاصه بعيدا عن الفيجوال ستديو تعمل delete جيدا.

سؤالى هو كيف استطيع تخطى هذه المشكله بالله عليكم؟؟

و الله ولى التوفيق

1

مدونتي: C++ Tips and Tricks

#2

لماذا لا تقوم بعمل Global Overloading لـ new و delete و بذلك تقوم بكتابة الـ Memory Manager خاص بك بدلاً من خلط الـ Standard Allocators مع الدوال التي تستخدمها.

بالطبع ستستخدم الدوال التي ذكرتها لكتابة الـ Memory Manager, و لكن لن تقع في مشكلة اختلاط مدراء الذاكرة.

سؤال جانبي, لماذا تستخدم دوال Windows مباشرة, لماذا لاتستخدم الـ Standard Allocators مباشرة؟ هل لديك سبب معين أم أنك تقوم بالتعديل على قطعة كود مكتوبة أصلاً,

تحياتي...

تم تعديل هذه المشاركة بواسطة Khaled.Alshaya في 21 مارس 2010 في 01:12

#3

اهلا أخى خالد

اقتباس

لماذا لا تقوم بعمل Global Overloading لـ new و delete و بذلك تقوم بكتابة الـ Memory Manager خاص بك بدلاً من خلط الـ Standard Allocators مع الدوال التي تستخدمها.

بالطبع ستستخدم الدوال التي ذكرتها لكتابة الـ Memory Manager, و لكن لن تقع في مشكلة اختلاط مدراء الذاكرة.

سؤال جانبي, لماذا تستخدم دوال Windows مباشرة, لماذا لاتستخدم الـ Standard Allocators مباشرة؟ هل لديك سبب معين أم أنك تقوم بالتعديل على قطعة كود مكتوبة أصااً,

فى الواقع سؤالك الجانبى هو محور الموضوع فى الأصل بالنسبه لى، حيث ان سبب استخدامى لدوال الويندوز مباشرة هو عدم وجود امكانية تحجيم مؤشر لمساحة معينه بالذاكره داخل الـ Cpp.

سأعطيك مثال: قمت بعمل فئة للتعامل مع النصوص و هذه الفئه تحتوى على الداله Insert و شكلها كالتالى

// insert str in cuurent instance at specified index
StringA& Insert(const StringA& str, int32 start_index);

فالنفترض ان المستخدم لديه نسخة من الفئه معرفة كالتالى

StringA str = "Welcome in Arab";

و بعدها اراد اضافة النص "Team2000" فى نهاية الجمله السابقه بإستدعائه الداله Insert بالشكل التالى

str.Insert("Team2000", 15);

فى هذه الحاله و على اعتمادنا على المعامل new و delete سأقوم بحجز مساحة جديده بحجم النص القديم و الجديد يليها نسخ النص القديم بالكامل ثم النص الجديد ثم تحرير النص القديم، داخل لغة الـ c كل ما يحدث هو اعادة تحجيم المساحه التى يشير لها مؤشر النص بإستخدام realloc ثم نسخ النص الجديد فى نهاية المساحه.

داخل الـ c احيانا اذا لم يتاح تحجيم المساحه الحاليه لأخرى اكبر يتم حجزها داخل مكان جديد و يتم نسخ القيم الموجوده بالمكان القديم للمكان الجديد ثم العوده بمؤشر للمكان الجديد و تحرير القديم و لكن هذا يقوم به نظام التشغيل. (فى حالتى هذا الأمر تم منعه حيث اما اعادة التحجيم او فشل عملية التحجيم).

ما اريد قوله هو انى اتعامل مع primitive data types و لا يوجد لهم constructors و بالتالى استخدام new و delete معهم يماثل تماما استخدام اى وسيلة اخرى لحجز الذاكره الخاصه بهم، بالإضافة ان عملية التحجيم ستزيد من كفائة الكود فمثلا تخيل ان النص يحجز مساحة 60 كيلو من الذاكره و المستخدم اراد اضافة حرف فى نهاية النص الموجود فى الوضع الحالى احتمالية الفشل قد تكون كبيره لعدم وجود chunk متوفره بهذا الحجم.

و الله ولى التوفيق

تم تعديل هذه المشاركة بواسطة Muhammad alaa في 21 مارس 2010 في 03:31

مدونتي: C++ Tips and Tricks

مواضيع مشابهة