سؤال

هل هناك طريقة portably تحديد العلوي والسفلي ملزمة على باطل-مؤشر القيم في ANSI C89/ISO C90? (أنا حاليا لم يكن لديك نسخة من معيار معي (وأنا واحد في المنزل).بالطبع إذا كان الفراغ-مؤشر القيم هي ضمان أن تكون موقعة هذه المهمة تافهة (عن طريق sizeof(الفراغ *));ومع ذلك لا أذكر إذا كان هذا هو مضمون أم لا.أستطيع أن أفكر في عدد قليل جدا من عدم كفاءة الخوارزميات (الزيادة حتى تجاوز ، الخ) ، ولكن أود أن أعرف إذا كان أي شخص لديه رخيصة نسبيا (من حيث الوقت-التعقيد) و المحمولة طريقة لحساب هذه الحدود.)

- تحرير -

أيضا: هل هناك المحمولة طريقة لتحديد صلاحية مؤشر القيم ؟

لماذا: هذا جاء في نقاش مع زميل في العمل و الحيرة لي.أنا لا أعرف ما هو العامل ، ولكن أريد فقط أن أعرف لأن أنا مهتم!:-)

هل كانت مفيدة؟

المحلول

لا يوجد المحمولة طريقة لتحديد ما إذا كان المؤشر غير صالح أو لا.عليك أن تعرف ما هو نوع من ذاكرة النظام كنت تتعامل مع.اعتمادا على نظام التشغيل والمعالج ، قد أو قد لا تكون طريقة الاستعلام عن الذاكرة الظاهرية مدير صفحة الجداول لتحديد صالحة يتراوح من المؤشرات.

على سبيل المثال ، على لينكس, يمكنك فحص خاص mmap الملف تحت /proc للحصول على خريطة الذاكرة الظاهرية العملية.هنا مثال من cat القراءة الخاصة بها خريطة الذاكرة:

$ cat /proc/self/mmap
08048000-0804c000 r-xp 00000000 09:00 5128276                            /bin/cat
0804c000-0804d000 rw-p 00003000 09:00 5128276                            /bin/cat
0804d000-0806e000 rw-p 0804d000 00:00 0                                  [heap]
f7ca7000-f7e40000 r--p 00000000 09:00 3409654                            /usr/lib/locale/locale-archive
f7e40000-f7e41000 rw-p f7e40000 00:00 0 
f7e41000-f7f68000 r-xp 00000000 09:00 2654292                            /lib/tls/i686/cmov/libc-2.3.6.so
f7f68000-f7f6d000 r--p 00127000 09:00 2654292                            /lib/tls/i686/cmov/libc-2.3.6.so
f7f6d000-f7f6f000 rw-p 0012c000 09:00 2654292                            /lib/tls/i686/cmov/libc-2.3.6.so
f7f6f000-f7f72000 rw-p f7f6f000 00:00 0 
f7f83000-f7f85000 rw-p f7f83000 00:00 0 
f7f85000-f7f9a000 r-xp 00000000 09:00 2637871                            /lib/ld-2.3.6.so
f7f9a000-f7f9c000 rw-p 00014000 09:00 2637871                            /lib/ld-2.3.6.so
ff821000-ff836000 rw-p 7ffffffea000 00:00 0                              [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0                                  [vdso]

يمكنك أن ترى نطاقات صالحة المؤشرات ، جنبا إلى جنب مع بت مشيرا إلى إذا كانت الذاكرة هي (r)eadable ، و (ث)ritable ، e(x)ecutable ، أو (p)تستاء (أيلا تقسيم القرص الصلب).

نصائح أخرى

مؤشرات مكفولة المواصفات أن تكون غير موقعة.ولكن لماذا كنت ترغب في العثور على الحدود ؟ "كل شيء بين 0x00000001 و 0xffffffff" ليس حقا مفيدة الاختبار ، منذ عدد من صالح المؤشرات سوف يكون بعض فرعية صغيرة من ذلك.

الفراغ * هو دائما كبيرة بما يكفي لعقد مؤشر إلى عنونة الذاكرة.أي استخدام آخر ممنوع منعا باتا من دوري البيسبول الجمعيات.

على سبيل المثال:Dec-10 36 بت مع 36 بت الكلمات.حتى الآن كانت عناوين 18 بت وأنت تحمل 2 المؤشرات في أي تسجيل/كلمة.

نعم - هذا مثال متطرف.إذا كان يجب أن تفعل الرياضيات مع مؤشرات, sizeof صالحة ؛ ولكن القيام مؤشر الرياضيات على شيء غير متجاورة مجموعة dodgier من المراوغة.

وأخيرا - لا تستخدم 'الفراغ *' لتخزين مؤشر إلى كائن أو مؤشر الأعضاء في C++.العديد من مترجم التنفيذ فعلا استخدام متعددة 'المادية' مؤشرات لتنفيذ متعددة الإرث من الخرسانة (جزئيا أو الخرسانة) الطبقات.في الواقع هذا لم يأتي لأن عدد قليل جدا من الناس استخدام وراثة متعددة في هذا الطريق, و عندما تفعل ذلك ، نادرا جدا شريحة unslice المؤشرات.عندما لا تأتي, انها حقا من الصعب معرفة ما حدث.

عليك أن تتبين قيمة عدد صحيح الذي void * يمكن أن يلقي الفعلية نمط بت في الذاكرة - صب void * إلى عدد صحيح نوع قد تنطوي على التحويلات!

على افتراض sizeof(void *) == sizeof(long), ، void * p التالية قد تكون خاطئة:

((long)p) == *((long *)&p)

أيضا ، فإن معيار لا يحدد ما إذا كان هناك حتى هو صحيح اكتب كبيرة بما يكفي لعقد قيم جميع صالحة المؤشرات!

لذلك فقط لا توجد المحمولة طريقة لفعل ما تريد القيام به...

وبصرف النظر عن المنطقة التي تتطابق مع NULL, لا يوجد (المحمولة) التقييد على عناوين الذاكرة في كل شيء.بما فيه الكفاية تصلب نظام التشغيل يمكن الاستفادة من مختلف وحدة المعالجة المركزية/نظام التشغيل آليات العرض كل عملية عشوائية و موزعة بشكل جيد عناوين مع كل استدعاء malloc () ، و موقف مستقل قابل للتنفيذ بالإضافة إلى ASLR يمكن أن تسمح بتشغيل تعليمات برمجية من أي عنوان.

وأنا أعلم أن على Win32, 64 بت مؤشرات توقع الموسعة.انها متعة لتفقد 32 بت minidump من جهاز 64-بت إذا لم توقع تمديد المؤشرات.

انظر هنا كيف 64 بت مؤشر (POINTER_64) يعمل على Win32.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top