الدرس 23: calloc وrealloc والمصفوفات الديناميكية
في الدرس السابق تعرّفنا على malloc — التي تحجز كتلة لكنها تترك فيها بيانات مهملة. تذهب calloc(n, size) خطوة أبعد: فهي تحجز وتُصفّر كل بايت أيضًا. أما realloc(p, new_size) فتغيّر حجم كتلة موجودة — تكبّرها أو تصغّرها — لكن انتبه: قد تنقل الكتلة إلى عنوان جديد، لذا خزّن النتيجة دائمًا في مؤشر مؤقت: int
realloc أشبه بالانتقال إلى وحدة تخزين أكبر: قد تنقل شركة النقل كل أغراضك إلى وحدة جديدة في مكان آخر وتسلّمك مفتاحًا جديدًا. لا ترمِ المفتاح القديم أبدًا قبل أن يصبح الجديد في يدك — وإلا، إذا فشل النقل، تكون قد خسرت الوحدة القديمة أيضًا.
- calloc(n, size)
- تحجز كتلة لعدد n من العناصر حجم كل منها size بايت — وتُصفّر أيضًا كل بايت.
- realloc(p, new_size)
- تغيّر حجم كتلة موجودة. تُحفظ القيم، لكن الكتلة قد تنتقل إلى عنوان جديد.
- مؤشر مؤقت (tmp)
- النمط الآمن: int *tmp = realloc(arr, ...); وفقط إذا لم يكن tmp مساويًا لـ NULL — arr = tmp;. بهذا لا تُفقد الكتلة الأصلية عند الفشل.
- السعة
- كم عنصرًا يمكن أن تحتوي الكتلة. في المصفوفة الديناميكية، عندما تنفد السعة — العُرف هو مضاعفتها باستخدام realloc.
- مصفوفة ديناميكية
- مصفوفة في الكومة (heap) يتحدد حجمها في وقت التشغيل ويمكن أن تنمو عند الحاجة — على خلاف المصفوفة العادية ذات الحجم الثابت.