الشبكة العربية لمطوري الألعاب

مبتدئ  أحمد عبد العظيم مشاركة 11

alright here's my trial, and the comments marking the part that confuses me


{
  int a = 10;
  int *p = new int;
  {
     int *o = new int;
     int *q = new int;
     *o = 8;
     *q = 4;  
     *p = 5;
     p = q;        // 'p' and 'q' now point at the same memory address 
     delete o;     // memory pointed at by 'o' is freed now
  }


  {
     *p = 1;       // the memory address of 'p' (and 'q') holds the value '1'
     delete q;     // now the part I don't understand, if I delete q, is p deleted automatically?
     p = &a;       // then how come i still can use it after 'delete q'?
  }
  *p = 2;
}
*p = 6; 
delete p;          // I need that line, right?

محترف مشرف عبد اللطيف حاجي علي مشاركة 12

أخيراً أنا في المنزل حيث يمكنني الكتابة بالعربية ☺


01. {
02.   int a = 10;
03.   int *p = new int;
04. {
05.     int *o = new int;
06.     int *q = new int;
07.     *o = 8;
08.     *q = 4;  
09.     *p = 5;
10.     p = q;
11.  }
12. 
13.   {
14.     *p = 1;
15.     p = &a;
16.  }
17.  *p = 2;
18. }

السطر الثالث، الخامس والسادس كما تعلم يعرف مؤشراً ويحجز مكاناً في الذاكرة لعدد صحيح ثم يضع عنوان هذا المكان في المؤشر p, o, q بالترتيب. لندعو هذه الأمكنة في الذاكرة ب، ث، ج
إذا يجب أن ننادي delete ثلاث مرات. مكان النداء يجب أن يكون بعد آخر استخدام لهذه الذاكرة وقبل أن نفقد عنوانها (إذا فقدنا العنوان لن نستيطع تحرير الذاكرة المحجوزة)
السطور 7 و 8 و 9 تغير القيم في الذاكرة التي تشير لها المؤشرات دون تغيير قيم المؤشرات
السطر العاشر يغير قيمة المؤشر p. لكي يؤشر إلى ث. علينا أن نسأل أنفسنا: هل فقدنا أحد العناوين قبل تحريها بهذا السطر. الجواب طبعاً هو نعم لأن p كان المتغير الوحيد الذي يحمل عنوان ب . لذلك يجب أن نضيف "delete p" قبل هذا السطر مباشرة.
يجب أيضاً أن نسأل نفس السؤال عند السطر 11. حيث أن المتغيرين q و o لهما مجال محدود بالأقواس وخارج هذه الأقواس نفقد هذين المتغيرين (و قيمهما وهي عناوين ث وج). لذلك يجب أن نضيف "delete o" قبل السطر 11 وبعد السطر 7.
لكن يجب ألا ننادي "delete q" هنا. لأننا لم نفقد عنوان ث بعد. حيث أننا وضعناه في المتغير p. تحرير الذاكرة هنا سيوقعنا في مشكلة في السطر 14 حيث نغير ث.
لكن في السطر 15  نقوم بتغيير قيمة المؤشر p. لذلك سنخسر عنوان ث وهنا يجب أن ننادي "delete p"  قبل هذا السطر مباشرة.
الآن عندما نخرج من آخر سطر 18 فإننا نفقد جميع المتغيرات بما فيها p. فهل هذا يعني أننا يجب أن ننادي delete? الجواب طبعاً لا ﻷن p الآن يؤشر إلى a الذي تم حجزه على الـ stack.

لاحظ أننا قمنا بثلاث نادءات لـ delete لتحرير الأماكن الثلاثة التي قمنا بحجزها.
لاحظ أيضاً أن الناءات كانت مرة على p ومرة على o ومرة على p. ولم ننادي delete على q. ذلك لأن أسماء المتغيرات لا يهم ما يهم هو قيمها.

عبد اللطيف حاجي علي
مبرمج
In|Framez

مبتدئ  أحمد عبد العظيم مشاركة 13

في 14/ذو الحجة/1432 09:29 م، قال عبد اللطيف حاجي علي بهدوء وتؤدة:

الآن عندما نخرج من آخر سطر 18 فإننا نفقد جميع المتغيرات بما فيها p. فهل هذا يعني أننا يجب أن ننادي delete? الجواب طبعاً لا ﻷن p الآن يؤشر إلى a الذي تم حجزه على الـ stack.

and stack is freed automatically when we go out of scope so we don't need to call 'delete p'

if I was in a cartoon I would have a lamp over my head now 😄 ,
 
thanks Abdul-Latif for your excellent explanation. I can now
 
Jazak Allah Khairan

just one last question before I can say I understand the whole concept of pointers 😳

*p=6; in the last line would give an error because *p was defined on the stack, right?

محترف مشرف عبد اللطيف حاجي علي مشاركة 14

تقصد أن p يؤشر إلى متغير على الـ stack.
لكن السبب هو أن المتغير الدي يؤشر له p قد تم تحريره اوتوماتيكياً عندما أصبح خارج نطاق رؤيته، كونه معرف على الستاك.
تماماً كالمشكة في الكود التالي

int *p = new int;
*p = 5;
delete p;
*p = 2;

عبد اللطيف حاجي علي
مبرمج
In|Framez