ورود

نسخه کامل مشاهده نسخه کامل : مشکل در حذف اشاره گر



SH@HIN
22-12-2012, 12:57
سلام دوستان
من تو محیط Visual Studio برنامه مینویسم به زبان C++ (Console)
یه مشکلی که برام پیش اومده این هست
این کد رو نگاه کنید

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

برنامه اجرا میشه و به درستی کارش رو انجام میده منتها وقتی به قسمت detele میرسه این ارور رو میده


برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

میخواستم بدونم مشکل از کجاست
ممنون

god of war 2
22-12-2012, 14:29
سلام.
من کدتونو توسط کامپایلر MinGW کامپایل کردم و بدون مشکل اجرا شد!
اما اشکالاتی در کدتون هست مثلا در خط:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
هیچ لزومی نداره که وقتی طول یک آرایه رو میدونید و از طرفی هم میدونید که حوزه کاریش با اتمام تابع تمام میشه اون آرایه رو بصورت داینامیک ایجاد کنید. میتونید براحتی اون آرایه رو به شکل زیر تعریف کنید:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
و این آرایه با اتمام تابع بصورت اتوماتیک آزاد میشود.
و یه نکته ایی هم که وجود داره اینه که شما آرایه ایی با طول 1 ایجاد کردید! اگر از این آرایه برای نگهداری جمله استفاده کنید احتمال خطا و کرش شدن برنامه بسیار زیاد هست. یک آرایه کاراکتری برای نگهداری جمله همواره به آخرین خانه آرایه برای نگهداری کاراکتر پوچ نیاز داره و در آرایه ایی با طول 1 یعنی اندیس های [0] , [1] شما فقط مجاز به استفاده از اندیس 0 هستید.
اشکال دوم در کدتون در خط :

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
میباشد که اندیس فراتر از حد مجاز آرایه هست.

SH@HIN
22-12-2012, 14:52
این مثال رو فقط برای اینکه نشون بدم چه اروری به وجود میاد نوشتم و اگرنه که بله برای آرایه با طول مشخص نیازی به آرایه پویا نیست
بعد در مورد اون 1 هم که گذاشتم ، اگر آرایه روی حافظه آزاد تعریف بشه و طولش از حد مشخص شده بیشتر بشه آرایه به طور اتوماتیک این افزایش فضا رو انجام میده !(البته من طول ارایه رو هم به صورت متغییر تست کردم ، یعنی اول از کاربر تعداد عناصر آرایه رو گرفتم بعد به جای 1 اون متغییر رو قرار دادم منتها باز هم همین اتفاق افتاد ! )

در مورد cout هم اگر ارایه نمیتونست فضا رو افزایش بده طبیعتا نباید کاراکتر خانه دوم ارایه رو نشون میداد ، که نشون میده !
یه سوال دیگه
میشه آرایه با طول داینامیک تعریف کرد منتها روی حافظه آزاد نباشه؟! یعنی دیگه نیازی به حذف پوینتر نباشه و برنامه اتوماتیک حافظه رو آزاد کنه

god of war 2
22-12-2012, 15:18
اگر آرایه روی حافظه آزاد تعریف بشه و طولش از حد مشخص شده بیشتر بشه آرایه به طور اتوماتیک این افزایش فضا رو انجام میده

در مورد cout هم اگر ارایه نمیتونست فضا رو افزایش بده طبیعتا نباید کاراکتر خانه دوم ارایه رو نشون میداد ، که نشون میده !
چنین چیزی در هیچکدام از استاندارد های این زبان تعریف نشده! اما ممکنه در شرایطی این اتفاق بیفته که یک توضیح مختصر میدم.
احتمالا میدونید که آرایه ها بصورت متوالی و پشت سرهم در حافظه ذخیره میشن و آدرس هر خانه توسط اندیس بصورت مستقیم محاسبه میشه. این شرایط این حالتو به وجود میاره که اگر شما مثلا در آرایه ایی به طول 4 خانه قصد دسترسی به خانه 6 را داشته باشید, آدرس آن محاسبه شده و برنامه برای دسترسی به خانه 6 تلاش میکند. اما اتفاقاتی که در این لحظه ممکن هست رخ بده میتونه متفاوت باشه برای مثال:
1- در خوش بینانه ترین حالت دسترسی با موفقیت انجام میشه و شما میتونید در آن خانه حداقل عملیات خواندن رو انجام بدید.(البته این اتفاق در سیستم عامل های قدیمی ممکن هست و در سیستم عامل های امروزی معمولا با خطا مواجه میشود)
2- کامپایلر این مورد رو تشخیص میدهد و پیغام دسترسی به اندیس غیر مجاز رو صادر میکند و کد شما اصلا کامپایل نمیشود.
3- برنامه در هنگام اجرا دقیقا زمانی که اجرا به آن قسمت از کد میرسد پیغام "تلاش برای دسترسی به حافظه ایی خارج ز اندیس میدهد" مانند پیغامی که برای شما داده است:

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
4- برنامه بدون هیچ پیغامی مستقیما با کرش مواجه میشه و به سرعت بسته میشه.
با توجه به مطلب بالا میبینید که این کار چقدر میتونه احتمال خطا را افزایش بده و این عمل یک کار غیر استاندارد و غلط میباشد.



میشه آرایه با طول داینامیک تعریف کرد منتها روی حافظه آزاد نباشه؟! یعنی دیگه نیازی به حذف پوینتر نباشه و برنامه اتوماتیک حافظه رو آزاد کنه
خیر.
تمام متغییر هایی که بصورت داینامیک تعریف میشوند توسط عملگر new در ++C ویا توابع malloc , alloc , ... در C همگی در حافظه heap قرار میگیرند و این متغیر ها حتما پس از اتمام کار باید توسط برنامه نویس آزاد شوند!
متغییر های غیر داینامیک که حوزه فعالیت دارند و بصورت اتوماتیک آزاد میشوند, در قسمت دیگری از حافظه قرار میگیرند و اندازه دقیق آنها در زمان کامپایل باید مشخص باشد.

_H2_
28-12-2012, 12:16
سلام
- مورد اول:
گمان نکنم انجمن مناسبی را برای پرسش انتخاب کرده باشید.
زبان های و تکنولوژی های مورد بحث در این انجمن به نوعی به فضای کاری Net Framework. مرتبط هستند که از شاخص ترین زبان های مرتبط میتوان از #C و VB.Net و VC++.Net و #J و... نام برد.
بخش مربوطه ([ برای مشاهده لینک ، لطفا با نام کاربری خود وارد شوید یا ثبت نام کنید ])


- مورد دوم
من کد شما را (با یک کاراکتر تغییر) بدون مشکل اجرا کردم.
در واقع مشکل شما از delete نیست و مربوط به ابعاد آرایه تان میشود...
فرمان cin به صورت Ascii-Z کار میکند به این معنی که برای وارد کردن کلمه Ali شما باید خودتان در کدتان تضمین دهید که چهار کاراکتر خالی فضا دارید...
بجز این مورد باید خودتان مراغب عدم خروج از ابعاد آرایه باشید، کاری که در خط cout از آن تخطی کرده اید...


یعنی دیگه نیازی به حذف پوینتر نباشه و برنامه اتوماتیک حافظه رو آزاد کنه
دو مورد ذکر شده و همین موردی که خودتان عنوان کردید و بسیاری موارد زیر و درشت دیگر، از جمله موارد تفاوت زبان های Native در مقابل Managed است.
فقط زبان های Managed است که برنامه نویس را از این دقدقه های فکری آزاد میکند ..
مثلاً در بالای 90% موارد (موارد غیر مرتبط با منابع سیستم عامل) مفهوم مخرب و delete و... کلاً بی معنی است و حتی کدی مانند این هم کاملاً بدون مشکل و صحیح است...

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید

کد صحیح شما

برای مشاهده محتوا ، لطفا وارد شوید یا ثبت نام کنید
آزمایش با استفاده از یک کلمه سه حرفی با تمام موارد تطبیق دارد.
موفق باشید.