التخصيص الديناميكي - malloc()
جزء من قسم المنطق وتدفق التنفيذ في رحلة C على Coddy. الدرس 32 من 63.
الآن ستتعلّم عن malloc()، وهي الدالة الأساسية لطلب memory من الـ heap أثناء تنفيذ البرنامج. تمثّل الدالة malloc() المصطلح "memory allocation"، وتتيح لك إجراء allocate ديناميكيًا لـ memory عند الحاجة إليها، بدلًا من التصريح عن متغيرات ذات حجم ثابت أثناء الترجمة.
تأخذ الدالة malloc() وسيطًا واحدًا: عدد وحدات البايت التي تريد allocateها. وتُرجع void pointer إلى كتلة الذاكرة allocated، أو NULL إذا فشلت عملية التخصيص. وبما أنها تُرجع void pointer، يمكنك إسنادها مباشرةً إلى pointer من نوع محدد؛ ويُعد إجراء التحويل الاختياري في C (بخلاف C++، الذي يتطلبه).
#include <stdlib.h>
int *ptr = (int*)malloc(sizeof(int)); // خصص ذاكرة لعدد صحيح واحد
// ptr يشير الآن إلى موقع ذاكرة يمكنه تخزين عدد صحيحالميزة الأساسية لـ
malloc()هي المرونة - يمكنك طلب مقدارmemoryالذي تحتاج إليه بالضبط أثناء وقت التشغيل، وتظل هذه الـmemoryمتاحة حتى تقوم بتحريرها صراحةً. وهذا مفيد بشكل خاص عندما لا تعرف مقدارmemoryالذي ستحتاج إليه إلا بعد تشغيل برنامجك.
تذكّر أن include <stdlib.h> لاستخدام malloc()؛ ويُعدّ تحويل المؤشر void returned اختياريًا في C، إذ يُحوَّل تلقائيًا إلى النوع الذي تُسنِده إليه.
التحدي
سهلاكتب برنامج C يوضّح dynamic memory allocation باستخدام malloc() لإنشاء والعمل مع integer واحد في heap. يجب أن يقوم برنامجك بما يلي:
- استخدم
malloc()لإجراء dynamic allocation لـ memory من أجل integer واحد - حوّل void pointer المُعاد إلى integer pointer
- اقرأ قيمة integer من user input
- store قيمة input في memory المُخصّصة ديناميكيًا باستخدام dereference operator
- اطبع القيمة stored بالتنسيق:
Stored value: [value] - احسب square للقيمة وstore النتيجة في same memory location
- اطبع القيمة squared بالتنسيق:
Squared value: [value]
تذكّر أن include ترويسة <stdlib.h> لاستخدام malloc(). يجب أن يوضّح برنامجك workflow الأساسي لـ dynamic memory allocation: طلب memory من heap، واستخدامها لتخزين البيانات ومعالجتها، والعمل مع memory المُخصّصة من خلال pointer operations.
على سبيل المثال، إذا أدخل المستخدم 7، فيجب أن يكون الناتج:
Stored value: 7
Squared value: 49يعرّفك هذا التحدي على المفهوم الأساسي لـ dynamic memory allocation، حيث يتم طلب memory أثناء runtime بدلًا من تثبيتها أثناء compile time، مما يمنح برامجك مرونة أكبر في استخدام memory.
جرّب بنفسك
#include <stdio.h>
#include <stdlib.h>
int main() {
// اقرأ الإدخال
int input_value;
scanf("%d", &input_value);
// TODO: اكتب الكود الخاص بك أدناه
// 1. استخدم malloc() لتخصيص ذاكرة لعدد صحيح واحد
// 2. حوّل المؤشر المُرجع إلى int*
// 3. خزّن قيمة الإدخال في الذاكرة المخصصة
// 4. اطبع القيمة المخزنة
// 5. احسب وخزّن المربع في نفس الموقع
// 6. Print the squared value
return 0;
}يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس المنطق وتدفق التنفيذ
1أساسيات المؤشرات
ما هو المؤشر؟الإعلان عن المؤشراتعامل العنوان (&)عامل إلغاء المرجعية (*)مؤشرات NULLمراجعة: أساسيات المؤشرات4مشروع: أداة نصوص بسيطة
نظرة عامة على المشروععد الأحرف2المؤشرات والمصفوفات
أسماء المصفوفات كمؤشراتعناصر المصفوفة - المؤشراتالعمليات الحسابية على المؤشراتمقارنة المؤشراتمراجعة: التنقل في المصفوفة باستخدام المؤشرات5المؤشرات والدوال
التمرير بالقيمةتمرير المؤشرات إلى الدوالتعديل المتغيرات عبر المؤشراتمثال كلاسيكي: التبديلتمرير المصفوفات إلى الدوالملخص: وسائط المؤشرات في الدوال8الهياكل والمؤشرات
المؤشرات إلى الهياكلعامل السهم (->)تمرير الهياكل بالقيمةتمرير مؤشرات الهياكلالتخصيص الديناميكي للهياكلمراجعة: تعديل الهياكل باستخدام المؤشرات11تحديات المراجعة النهائية
مراجعة: دمج السلاسل النصية الديناميكيمراجعة: مصفوفة من الـ Structsمراجعة: عداد تكرار الكلمات3مصفوفات الأحرف والسلاسل النصية
السلاسل النصية كمصفوفات charالمُنهي الصفري (Null Terminator)إدخال السلاسل النصية باستخدام scanfاستخدام strlen()استخدام strcpy()استخدام strcat()استخدام strcmp()مراجعة: دوال السلاسل النصية الأساسية6إدارة الذاكرة
ذاكرة Stack مقابل Heapالتخصيص الديناميكي - malloc()استخدام sizeof() للتخصيصالتحقق من فشل التخصيصتحرير الذاكرة باستخدام free()التخصيص باستخدام calloc()ملخص: المصفوفة الديناميكيةتدرّب بنفسك: مترجم C عبر الإنترنت