المؤشرات المتدلية
مخاطر الاستخدام بعد التحرير
المؤشرات المتدلية درس مجاني في C Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في C Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة C Academy 4 دروس في المجموع.
ما هو المؤشر المتدلّي
المؤشر المتدلّي هو مؤشر يشير إلى ذاكرة جرى تحريرها بالفعل أو لم تعد صالحة لسبب آخر.
يؤدي استخدامه إلى سلوك غير معرّف: مثل تعطل البرنامج أو تلف البيانات أو ظهور أخطاء صامتة.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 5;
printf("%d\n", *p);
free(p);
p = NULL;
return 0;
}الاستخدام بعد التحرير
السبب الأكثر شيوعًا هو القراءة من خلال مؤشر أو الكتابة عبره بعد استدعاء free.
قد تكون الكتلة قد أُعيد استخدامها لشيء آخر.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 42;
free(p);
/* Reading *p here would be use-after-free. */
p = NULL;
printf("avoided use-after-free\n");
return 0;
}التعيين إلى NULL بعد التحرير
يؤدي تعيين المؤشر إلى NULL مباشرةً بعد تحريره إلى تحويل الاستخدام غير المقصود إلى تعطل واضح، أو إلى استدعاء آمن وغير ضار للدالة free(NULL).
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *buf = malloc(10);
buf[0] = 'A';
free(buf);
buf = NULL;
if (buf == NULL) printf("buf is safely null\n");
return 0;
}إرجاع عنوان محلي
يؤدي إرجاع عنوان متغير محلي (على المكدس) إلى إنشاء مؤشر متدلٍّ؛ إذ يختفي المتغير عند عودة الدالة.
استخدم الكومة أو مرّر مخزنًا مؤقتًا بدلًا من ذلك.
#include <stdio.h>
#include <stdlib.h>
int *make_value(int v) {
int *p = malloc(sizeof(int));
*p = v;
return p;
}
int main(void) {
int *p = make_value(99);
printf("%d\n", *p);
free(p);
return 0;
}مؤشرات متعددة إلى كتلة واحدة
إذا كان مؤشّران يشيران إلى الكتلة نفسها، فإن تحريرها عبر أحدهما يجعل المؤشر الآخر متدلّيًا.
تتبّع الملكية بحيث لا يحرّر الكتلة إلا مالكها.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(sizeof(int));
*a = 7;
int *b = a;
printf("%d\n", *b);
free(a);
a = NULL;
b = NULL;
printf("both nulled\n");
return 0;
}التدلّي بعد realloc
عندما تنقل realloc كتلةً ما، يصبح أي مؤشر قديم إلى الموقع السابق متدلّيًا.
استخدم المؤشر الذي أعادته realloc فقط.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *a = malloc(sizeof(int));
a[0] = 1;
int *b = realloc(a, 50 * sizeof(int));
/* a may now be dangling; use only b. */
b[0] = 2;
printf("%d\n", b[0]);
free(b);
return 0;
}التحرير داخل دالة مساعدة
إذا حرّرت دالة مساعدة كتلةً ما، فسيبقى مؤشر المستدعي متدلّيًا. صفّره بعد الاستدعاء، أو صمّم الدالة المساعدة بحيث تستقبل مؤشرًا إلى مؤشر.
#include <stdio.h>
#include <stdlib.h>
void destroy(int **p) {
free(*p);
*p = NULL;
}
int main(void) {
int *p = malloc(sizeof(int));
*p = 5;
destroy(&p);
printf("p is %s\n", p == NULL ? "null" : "set");
return 0;
}لماذا يُعدّ خطيرًا
يُعدّ الاستخدام بعد التحرير خطيرًا لأن الذاكرة قد تحتوي الآن على بيانات أخرى. وقد تؤدي عمليات الكتابة إلى إتلاف حالة غير مرتبطة، كما يمكن للمهاجمين استغلال ذلك.
المؤشرات المتدلّية بسبب النطاق
يصبح المؤشر إلى متغير محصور في نطاق كتلة غير صالح بمجرد انتهاء تلك الكتلة. احتفظ بالمؤشرات مدةً لا تتجاوز عمر العناصر التي تشير إليها.
#include <stdio.h>
int main(void) {
int *p;
{
int x = 10;
p = &x;
printf("in scope: %d\n", *p);
}
/* p now dangles; do not dereference it here. */
printf("block ended\n");
return 0;
}اكتشاف المؤشرات المتدلّية
تكتشف أدوات مثل AddressSanitizer وValgrind الاستخدام بعد التحرير أثناء التشغيل، وتشير إلى السطر المحدد.
أنشئ البرنامج باستخدام أدوات كشف الأخطاء أثناء التطوير.
مراجعة دورة الحياة الآمنة في التعليمات البرمجية
خصّص الذاكرة، واستخدمها، وحرّرها، ثم صفّر المؤشر. يحافظ اتباع هذه الخطوات باستمرار على عدم تدلّي المؤشرات.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
if (!p) return 1;
*p = 123;
printf("%d\n", *p);
free(p);
p = NULL;
return 0;
}اختبار سريع
اختبر مدى فهمك للمؤشرات المتدلّية.
مراجعة
تعلّمتَ عن المؤشرات المتدلّية:
- تشير إلى ذاكرة محرّرة أو خارجة عن النطاق؛ واستخدامها سلوك غير معرّف.
- تجنّب إرجاع عناوين المتغيرات المحلية؛ ولا تستخدم مؤشرًا بعد
freeأو بعد أن تنقلreallocكتلةً ما. - عيّن المؤشرات إلى
NULLبعد التحرير، وتتبّع الملكية. - استخدم أدوات كشف الأخطاء وValgrind لاكتشاف الاستخدام بعد التحرير.
الأسئلة الشائعة
هل درس «المؤشرات المتدلية» مجاني؟
نعم — نص درس «المؤشرات المتدلية» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة C Academy، انتقل إلى CoddyKit PRO. تتضمن دورة C Academy 4 دروس في المجموع.
ماذا ستتعلم في «المؤشرات المتدلية»؟
مخاطر الاستخدام بعد التحرير تتمرن على C Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ C Academy؟
لا تُشترط خبرة سابقة. C Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «المؤشرات المتدلية»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس C Academy هذا؟
نعم. كل درس في C Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- malloc وfree
- calloc وrealloc
- تسرّبات الذاكرة
- المؤشرات المتدلية