ما الذي يسبب تعطل إعادة تعيين مؤشر العدد الصحيح؟

StackOverflow https://stackoverflow.com/questions/207800

  •  03-07-2019
  •  | 
  •  

سؤال

أنا جديد على C ولدي هذا السؤال.لماذا يتعطل الكود التالي:

int *a = 10;
*a = 100;
هل كانت مفيدة؟

المحلول

ولأن تحاول إرسال 100 إلى موقع الذاكرة 0x0000000A التي ربما لن المخصصة للبرنامج الخاص بك. وهذا هو،

int *a = 10;

وهذا لا يعني أن مؤشر "أ" ويشير إلى موقع في الذاكرة لها قيمة 10. وهذا يعني أنه يشير إلى معالجة 10 (0x0000000A) في الذاكرة. ثم، هل تريد أن تكتب شيء في هذا العنوان، ولكن لم يكن لديك "حقوق" للقيام بذلك، لأنه لا يتم تخصيص ذلك

ويمكنك محاولة ما يلي:

int *a = malloc(sizeof(int));
*a = 100;

وهذا من شأنه أن يعمل، على الرغم من عدم كفاءة فظيعة. إذا كنت بحاجة فقط لكثافة واحد، يجب أن مجرد وضعها في كومة ، وليس كومة . على أرتشيتيكوري 32 بت، وهو المؤشر 32 بت طويلة، وكثافة العمليات هو 32 بت طويلة جدا، لذلك الهيكل الخاص مؤشر إلى وسيلة الباحث يستغرق (<لأ href = "https://stackoverflow.com/questions / 197839 / غير-هناك-أي-الطريق إلى تحديد الحركة والحجم من تيار مصفوفة برمجيا، وإذا، وليس # 197872 "> على الأقل ) 8 بايت من مساحة الذاكرة بهذه الطريقة بدلا من 4. ونحن لم يذكر حتى القضايا التخزين المؤقت.

نصائح أخرى

وتحتاج إلى تعيين المؤشر إلى <م> موقع الذاكرة ، لا قيمة التعسفي (10).

int cell = 10;
int *a = &cell; // a points to address of cell
*a = 100;       // content of cell changed

جوابي لآخر السؤال عن الحرص مع C .

وأود أن أقترح تغيير طفيف في استخدام malloc ()، لأن كل الإجابات التي توحي استخدامه لتخصيص الذاكرة لكثافة العمليات. بدلا من:

a = malloc(sizeof(int));

وأود أن أقترح عدم تكرار نوع المتغير، لأن ما هو معروف من قبل المجمع وتكرار ذلك يدويا كل من يجعل رمز أكثر كثافة، ويدخل خطر الخطأ. إذا قمت لاحقا بتغيير إعلان لمنها مثلا.

long *a;

وبدون تغيير تخصيص، وكنت في نهاية المطاف تخصيص مقدار الخطأ من الذاكرة (في الحالة العامة، وعلى أجهزة 32 بت int وlong غالبا ما تكون نفس الحجم). انها والمنظمة البحرية الدولية، وأفضل لاستخدام:

a = malloc(sizeof *a);

وهذا يعني ببساطة "حجم نوع أشار في من قبل"، في هذه الحالة int، الذي هو بطبيعة الحال حق بالضبط. إذا قمت بتغيير نوع في إعلان على النحو الوارد أعلاه، وهذا الخط هو لا يزال الصحيح. لا يزال هناك خطر، إذا قمت بتغيير اسم المتغير على الجانب الأيسر من المهمة، ولكن على الأقل لم يعد لتكرار المعلومات دون داع.

ونلاحظ أيضا أن هناك حاجة إلى أي قوسين مع sizeof عند استخدامه على الكائنات الفعلية (أي متغيرات)، فقط مع أسماء الأنواع، التي تبدو وكأنها عبارات المدلى بها. sizeof ليس وظيفة، انها المشغل.

لأنك لم تقم أبدًا بتخصيص أي ذاكرة لـ.لقد قمت للتو بتخصيص بعض مساحة المكدس لمؤشر إلى ملف.

int *a = NULL;

a = malloc (sizeof (int));

if (a != NULL)
{
*a =10;
}

سيعمل.

وبدلاً من ذلك، يمكنك إعطاء عنوان لبعض المتغيرات الموجودة، والتي قد تعمل أيضًا.

أي.

int a* = NULL;
int b = 10;

a = &b;

وهذا يعني الآن أن تفعل شيئا من هذا القبيل

*a = 100;

سيتم أيضًا تعيين b ليكون == 100

ألق نظرة على هذا:http://home.netcom.com/~tjensen/ptr/pointers.pdf

السطر التالي،

int *a = 10;

يحدد مؤشر إلى عدد صحيح أ.أنت إذن نقطة المؤشر إلى موقع الذاكرة 10.

السطر التالي،

*a = 100;

يضع القيمة 100 في موقع الذاكرة المشار إليه بـ a.

المشكلة هي:

  1. أنت لا تعرف إلى أين تشير.(أنت لا تعرف قيمة موقع الذاكرة 10)
  2. أينما تشير النقطة، ربما ليس لديك الحق في تغيير تلك القيمة.من المحتمل أن تكون ذاكرة برنامج/عملية أخرى.أنت لص!

ولأن تقوم بتعريف مؤشر إلى int، تهيئة على المؤشر ل10 (عنوان)، ثم محاولة لتعيين قيمة إلى int على هذا العنوان. منذ الذاكرة في عنوان 10 لا ينتمي إلى العملية الخاصة بك، يمكنك الحصول على الحادث. هذا يجب أن تعمل:

int *a;
a = malloc(sizeof(int));
*a = 10;
printf("a=%i\n", *a);
free(a);

هل هذا الرمز حتى تجميع؟ 10 ليس للتحويل إلى int *، إلا إذا كنت يطرح مثل ذلك:

int *a = (int *) 10;
*a = 100;

في هذه الحالة، كنت تحاول إرسال 100 في عنوان الذاكرة في 10. وهذه ليست عادة عنوان ذاكرة صحيح، وبالتالي تعطل البرنامج.

وانها ربما تتعطل بسبب قمت بتعيين المؤشر إلى جزء من الذاكرة التي لم يكن لديك الوصول إلى وثم كنت تعيين بعض القيمة إلى ذلك الموقع الذاكرة (التي كنت لا يسمح لها بأن تفعل!).

هل يمكن أيضا كتابة على النحو التالي:

int* a = 10;
*a = 100;

ملاحظة التباعد مختلفة في السطر الأول. انها ليست النمط الشعبي، ولكن أنا شخصيا أعتقد أنه من أكثر وضوحا. انها بالضبط نفس المعنى إلى مترجم.

وبعد ذلك، قراءته بصوت عال:

"Pointer-to-int 'a' becomes 10"
"Value-pointed-to-by 'a' becomes 100"

واستبدال القيمة الفعلية:

"Value-pointed-to-by 10 becomes 100"

... الذي كنت أدرك أن 10 من غير المرجح أن نشير إلى قطعة من الذاكرة التي يمكن استخدامها.

هل سيكون الى حد كبير أبدا تعيين إلى مؤشر مع حرفي:

int* ptr = (int*)10;  // You've guessed at a memory address, and probably got it wrong
int* ptr = malloc(sizeof(int)); // OS gives you a memory address at runtime  

وأعتقد قد يكون هناك بعض <م> جدا وظائف مستوى منخفض حيث يمكنك تحديد عناوين الذاكرة مباشرة المطلقة. تنفيذ نواة مثلا؟

حسنا، في محاولة لإعطاء أبسط تفسير اليوم، بينما كان يحاول تعطيك صورة أكثر تفصيلا حول كل شيء. يتيح إضافة بعض الأقواس ونحن؟

(int*) a = 10;
(*a) = 100;

وأنت تحاول أن يكتب أربعة بايت في عنوان المدى [10-13]. تخطيط الذاكرة من البرنامج يبدأ عادة ما يكون أعلى، لذلك طلبك لا الكتابة بطريق الخطأ أي شيء من حيث ما في وسعها، ولا تزال وظيفة (من .data، .bss، وكومة على سبيل المثال). لذلك ينتهي فقط حتى تحطمها بدلا من ذلك، لأنه لم يتم تخصيص المدى العنوان.

ونقاط مؤشر إلى موقع الذاكرة وC الكتابة ثابتة تحدد نوع للمؤشر. على الرغم من أنك يمكن أن تجاوز المؤشر بسهولة. ببساطة:

(void*) v = NULL;

وهنا نذهب أبعد إلى الأشياء. ما هو مؤشر فارغة؟ انها ببساطة مؤشر يشير إلى معالجة 0.

ويمكنك أيضا إعطاء نوع البنية لالمؤشر:

struct Hello {
    int id;
    char* name;
};

...

struct Hello* hello_ptr = malloc(sizeof Hello);
hello_ptr->id = 5;
hello_ptr->name = "Cheery";

وطيب، ما هو malloc؟ Malloc يخصص الذاكرة وإرجاع مؤشر إلى الذاكرة المخصصة. أنه يحتوي على توقيع نوع التالية:

void* malloc(size_t size);

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

free(hello_ptr);

وكل malloc تفعله لديها حجم العلامة في ذلك، لذلك لا تحتاج لبيان حجم قطعة أشرت ل-routine مجانا.

وطيب، ولكن شيء واحد، ما لم سلسلة أحرف تبدو وكأنها في الذاكرة؟ واحدة مماثلة ل"فرحان" على سبيل المثال. الجواب بسيط. انها مجموعة منتهية صفر بايت.

0.1.2.3.4.5. 6
C h e e r y \0
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top