الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تصرف غريب آخر في VC6 !

مغلق
بدأه آل عيد في 16 يوليو 2001 · 1 رد · 497 مشاهدة · في ارشيف قسم C/C++
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

الأخوة الأعزاء، طرأت لي مشكلة أخرى أثناء كتابتي لبعض البرامج وهي كالتالي :

[Code2]
#include

void main()
{
typedef char* STRING;
STRING Name;
Name = "This is a another ...";
cout << "What is your name? ";
cin >> Name;
cout <<"Hi " << Name << "nBye...n";
}

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

#2

السلام عليكم ،

أنت شكلك حاقد على الفيجوال سي++ ، وكل شوي تطلعلنا تصرفات غريبة .. :) :)

بعد أن جربت البرنامج وجدته يعمل في ال Release ولا يعمل في ال Debug . وكما ذكرت فإنه يعمل في ال Borland C++ ..

ورسالة الخطأ التي تظهر هي أنه قام البرنامج بعملية ممنوعة ولا يمكن الكتابة على هذه المنطقة من الذاكرة .

طبعا هذا البرنامج من الناحية البرمجية خاطئ مية المية . فالنوع الذي أنت قمت بتعريفه (String) وهو مؤشر إلى char . طبعا عندما تقوم بتعريف مثل هذا المتحول الذي تريد استخدامه يجب أن تسنده إلى موقع في الذاكرة محجوز مسبقا أو تحجز له بشكل ديناميكي من خلال new أو delete .. ولكن أنت في هذا البرنامج قمت بسناد هذا المؤشر من أجل أن يؤشر إلى constant string وأنت لست أكيد أين تكون متوضعة هذه السلسلة في الذاكرة ، فقد تكون في قسم الكود وليس في قسم المعطيات .

فالبرنامج التالي يكون صحيح :

void main()
{
	char str[] = "This is a another ...";	// Allocating in the stack

	typedef char* STRING;
	STRING Name;
	Name = str;

	cout << "What is your name? ";
	cin >> Name;
	cout <<"Hi " << Name << "nBye...n";
}

طبعا في الكود السابق ليس من الضروري أن تستخدم المتحول Name كوسيط من أجل الادخال .

=============

الآن لنأتي إلى تحليل المشكلة بشكل أكبر ..

كما ذكرت فإنك في برنامجك تجعل المؤشر Name يؤشر على constant string .. عندما قمت بتشغيل البرنامج في ال Debug فإن التعليمة cin سوف تكتب في الحجرات التي يؤشر عليها Name القيم الجديدة ولكن الويندوز يمنع ذلك لأن المنطقة على ما يبدو ليسة معطاة سماحية الكتابة .

قمت بالتأكد من ذلك فعلا فكتبت قيمة المؤشر بعد الاسناد (00429044) واستخدمت برنامج ال WinDisassempler ليقرأ لي أقسام الملف التنفيذي فوجدت أن ذاك العنوان يؤشر على المقطع (rdata.) وهذا المقطع هو للقرائة فقط ولايسمح بالكتابة عليه ..

بالنسبة لل Release وجدت أن المؤشر يؤشر على مقطع (data.) وهذا المقطع من أسمه طبعا يسمح بالقرائة والكتابة .

لكن لماذا في ال Debug تكتب ال constant strings في ذاك المقطع ؟ قمت بالبحث في ال MSDN فوجدت أن خيار المترجم (ZI/) الذي هو (debug info for edit and continue) يستخدم خيار المترجم (GF/) الذي هو (constant string poolong) وهذا الأخير يضع جميع السلاسل النصية الثابتة في (rdata.) . وطبعا هذا الخيار (ZI/) هو من أجل توليد معلومات للمنقح Debugger داخل الملف التنفيذي . وهو طبعا غير مفعل في نسخة ال Release .

إذا في نسخة ال Debug إذا أردت أن تجعل برنامجك يعمل يمكنك تغيير ذاك الخيار كالتالي :

  • إذهب إلى Projects ومن ثم Settings .
  • تأكد من أنك مختار Win32 Debug في Settings For .
  • إذهب إلى التاب C++ .
  • تأكد أنك مختار General في Category .
  • ثم في Debug Info اختر Program Databas .

إذا قمت بتلك الخطوات فإنك تلغي خيار المترجم (ZI/) ومنه يلغى (GF/) . ويعمل البرنامج في ال Debug .. ولكن في ال MSDN إذا ذهبت إلى (GF/) وقرأت عنها . تجد أنهم لا ينصحو بالكتابة إلى السلسلة التي تم حجزها عن طريق اسناد constant string إلى مؤشر ..

وأنا أنتظر التصرف الغريب الثالث ... :)

ومية السلامة ..

Coding on the Cloud and for the Cloud!

My Blog

هذا الموضوع مغلق.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…