freeCodeCamp/guide/arabic/c/Dinamic Memory Management/index.md

88 lines
7.0 KiB
Markdown
Raw Normal View History

---
title: Dinamic Memory Management
localeTitle: إدارة الذاكرة الديناميكية
---
# إدارة الذاكرة الديناميكية
في بعض الأحيان ، ستحتاج إلى تخصيص مساحات ذاكرة في الكومة المعروفة أيضًا باسم الذاكرة الديناميكية. هذا هو مفيد بشكل خاص عندما لا تعرف خلال وقت الترجمة كيف سيكون هيكل البيانات كبير (مثل مصفوفة).
## مثال
إليك مثال بسيط حيث نخصص مصفوفة تطلب من المستخدم اختيار البعد
`#include <stdio.h>
#include <stdlib.h>
int main(void) {
int arrayDimension,i;
int* arrayPointer;
scanf("Please insert the array dimension:%d",arrayDimension);
arrayPointer = (int*)malloc(sizeof(int)*arrayDimension);
if(arrayPointer == NULL){
printf("Error allocating memory!");
return -1;
}
for(i=0;i<arrayDimension;i++){
printf("Insert the %d value of the array:",i+1);
scanf("%d\n",arrayPointer[i]);
}
free(arrayPointer);
return 0;
}
`
كما ترون من أجل تخصيص مساحة في الذاكرة الديناميكية تحتاج إلى معرفة كيفية عمل المؤشرات في C. إن الوظيفة السحرية هنا هي `malloc` الذي سيعود كمخرج فارغ (وهو مؤشر إلى منطقة من نوع البيانات غير معروف) إلى مساحة الذاكرة الجديدة التي قمنا بتخصيصها للتو. دعونا نرى كيفية استخدام هذه الوظيفة خطوة بخطوة:
## تخصيص صفيف خلال وقت التشغيل
`sizeof(int)
`
لنبدأ من `sizeof` . يحتاج `malloc` إلى معرفة مقدار المساحة المخصصة لبياناتك. في الواقع ، سيستخدم المتغير `int` مساحة تخزين أقل ثم مساحة `double` . من غير الآمن عمومًا تحديد حجم أي نوع بيانات. على سبيل المثال ، على الرغم من أن معظم تطبيقات C و C ++ على أنظمة 32 بت تعرف النوع int لتكون أربع ثمانيات ، فقد يتغير هذا الحجم عند نقل الكود إلى نظام مختلف ، مما يؤدي إلى كسر الشفرة. `sizeof` كما يقترح اسم يولد حجم متغير أو نوع البيانات.
`arrayPointer = (int*) malloc(sizeof(int) * arrayDimension);
`
في هذا المثال ، يقوم malloc بتخصيص الذاكرة وإرجاع المؤشر إلى كتلة الذاكرة. حجم الكتلة المخصصة يساوي عدد البايتات لكائن واحد من نوع int مضروبًا في `arrayDimension` ، مما يوفر للنظام مساحة كافية متاحة. ولكن ماذا لو لم يكن لديك مساحة كافية أو `malloc` لا يمكن تخصيصها لبعض الأسباب الأخرى؟
## التحقق من إخراج malloc
لا يحدث هذا بشكل شائع ولكن من الجيد جدًا التحقق من قيمة متغير مؤشرك بعد تخصيص مساحة جديدة من الذاكرة.
` if(arrayPointer == NULL)
printf("Error allocating memory!");
`
سيكون هذا أيضًا مفيدًا جدًا أثناء مرحلة التصحيح وسيعمل على منع بعض الأخطاء المحتملة باستخدام آخر وظيفة مستخدمة في المثال.
## كلمة على الحرة ()
عادة يتم إلغاء تخصيص المتغيرات تلقائيًا عندما يتم تدمير نطاقها ، مما يؤدي إلى تحرير الذاكرة التي كانوا يستخدمونها. لا يحدث هذا بسيط عند تخصيص الذاكرة يدوياً باستخدام `malloc` . لمنع تسرب الذاكرة في برامج أكثر تعقيدًا ولإلغاء إنشاء القمامة في النظام ، يجب عليك تحرير منطقة الذاكرة المستخدمة حديثًا قبل إنهاء تنفيذ التعليمات البرمجية.
` free(arrayPointer);
`
في النهاية سوف تفهم بالتأكيد أن التحقق من قيمة `arrayPointer` كان ضروريا لمنع الخطأ باستخدام الوظيفة `free` . إذا كانت قيمة `arrayPointer` تساوي `NULL` قد يكون لديك expirencied نوع من الخطأ.
## وظائف أخرى مماثلة ل malloc
في بعض الأحيان ، لا تحتاج فقط إلى حجز مساحة جديدة من الذاكرة لعملياتك ، فقد تحتاج أيضًا إلى تهيئة جميع وحدات البايت إلى صفر. هذا هو ما يستخدم `calloc` ل. في حالات أخرى ، ترغب في تغيير حجم مقدار الذاكرة التي يشير إليها المؤشر. على سبيل المثال ، إذا كان لديك مؤشر يعمل كمصفف للحجم `n` وتريد تغييره إلى صفيف بحجم `m` ، فيمكنك استخدام `realloc` .
` int *arr = malloc(2 * sizeof(int));
arr[0] = 1;
arr[1] = 2;
arr = realloc(arr, 3 * sizeof(int));
arr[2] = 3;
`
## الأخطاء الشائعة
الاستخدام غير السليم لتخصيص الذاكرة الديناميكية يمكن أن يكون مصدرًا للثغرات كما رأينا من قبل. معظم الأخطاء الشائعة هي:
* عدم التحقق من فشل التخصيص لا يمكن ضمان تخصيص الذاكرة بنجاح ، وقد يقوم بدلاً من ذلك بإرجاع مؤشر فارغ. باستخدام القيمة التي تم إرجاعها ، دون التحقق من نجاح التخصيص ، يستدعي سلوكًا غير معروف. هذا عادة ما يؤدي إلى تعطل (بسبب خطأ تجزئة الناتج على dereference مؤشر nullference) ، ولكن لا يوجد أي ضمان أن يحدث تعطل لذا فإن الاعتماد على ذلك يمكن أن يؤدي أيضًا إلى حدوث مشكلات.
* تسريبات الذاكرة الفشل في إلغاء تخصيص الذاكرة باستخدام خيوط `free` لتراكم الذاكرة غير القابلة لإعادة الاستخدام ، والتي لم يعد يستخدمها البرنامج.
* أخطاء منطقية يجب أن تتبع جميع التوزيعات نفس النمط: التخصيص باستخدام `malloc` ، والاستخدام لتخزين البيانات ، إلغاء تخصيص باستخدام `free` . إذا كنت لا تتبع هذا النمط ، فعادةً ما يتم عرض خطأ التقطيع وسيتعطل البرنامج. يمكن أن تكون هذه الأخطاء عابرة وصعبة التصحيح - على سبيل المثال ، لا يتم استرداد الذاكرة المحررة عادةً على الفور من قبل النظام ، وقد تستمر المؤشرات المتدلية لفترة من الوقت وتبدو وكأنها تعمل.