ورود

View Full Version : سوال: منهدم کردن حافظه از نوع متغیر



fadakplus
پنج شنبه 16 دی 1389, 07:08 صبح
ااااااااااااااااااااااااا ااااااااااااااااااااااااا ااااااااااااااااااااااااا ا

jeson_park
پنج شنبه 16 دی 1389, 08:04 صبح
سلام
1-واضح تر بگید!
فکر کنم اون چیزی که توی ذهن شما هست درست نباشه
اگر درست برداشت کرده باشم شما می خواد یه متغیر درست منید بعد که ازش استفاده کردین اون رو پاک کنید و بعد که دوباره خواستین ازش استفاده کنید براش فضا تخصیص بدین
این چیزی که شما می خواین رو باید با اشاره گر پیاده سازی کنید و فکر نکنم راه دیگه ای داشته باشه
به این (http://www.exforsys.com/tutorials/c-plus-plus/c-plus-plus-memory-management-operators.html) لینک سری بزنید

2- خوب ثابت یعنی ثابت دیگه! :لبخند:
به کد زیر نگاه کنید شاید به دردتون خورد


char *const a = "example 1"; // a const pointer to (he claims) non-const data
a[8] = '2'; // Coplien says this is OK, but it's actually undefined

fadakplus
پنج شنبه 16 دی 1389, 19:03 عصر
با تشکرازjeson_park (http://barnamenevis.org/member.php?89354-jeson_park):
برای سوال دوم روش خوبی ارائه دادن ممنون&&دست مریزاد&&(اگه روشی غیراز این بود مارو خبرکنید)........(درسته ثابت یک ثایت ولی کلا یکم بده پادشاه زبانهای برنامه نویسی(++c)نه تونه این کارو بکنه!!!!!!!!!!!!!!!)
کلا می خوامی که یک ثابت تعریف کنم مثلا وconst s=10ومی خوام مقدار s روبه20 تغییر بدم!!!!!!!!!!!!!.
ولی برای سوال اول:
ببین می خوام هنگامی که متغیر(نه ازنوع اشاره گر وبصورت عادی ازنوع کلاس حافظه اتوماتیک یا هرنوع کلاس دیگر)تعریف کنم
()main
int a=20
بعد وقتی برنامه رو اجراکردیم(حال به هردلیلی )آن متغیر رو کلا می خوام حذف کنم(وقتی برنامه در حال اجراباشد(یعنی در زمان اجرا))

قسمت دوم سئوال اول::می خوام در زمان اجرا ونه بعد از کامپایل یعنی وقتی که نیاز داشته باشم در زمان اجرای برنامه یک متغیرمثلا int bتعریف کنم شدنی ایست!!!!!!!!!!!!!!!!!

mehdi.mousavi
شنبه 18 دی 1389, 11:04 صبح
با تشکرازjeson_park (http://barnamenevis.org/member.php?89354-jeson_park):
برای سوال دوم روش خوبی ارائه دادن ممنون&&دست مریزاد&&(اگه روشی غیراز این بود مارو خبرکنید)........(درسته ثابت یک ثایت ولی کلا یکم بده پادشاه زبانهای برنامه نویسی(++c)نه تونه این کارو بکنه!!!!!!!!!!!!!!!)
کلا می خوامی که یک ثابت تعریف کنم مثلا وconst s=10ومی خوام مقدار s روبه20 تغییر بدم!!!!!!!!!!!!!.
ولی برای سوال اول:
ببین می خوام هنگامی که متغیر(نه ازنوع اشاره گر وبصورت عادی ازنوع کلاس حافظه اتوماتیک یا هرنوع کلاس دیگر)تعریف کنم
()main
int a=20
بعد وقتی برنامه رو اجراکردیم(حال به هردلیلی )آن متغیر رو کلا می خوام حذف کنم(وقتی برنامه در حال اجراباشد(یعنی در زمان اجرا))

قسمت دوم سئوال اول::می خوام در زمان اجرا ونه بعد از کامپایل یعنی وقتی که نیاز داشته باشم در زمان اجرای برنامه یک متغیرمثلا int bتعریف کنم شدنی ایست!!!!!!!!!!!!!!!!!


سلام.
حقیقت اینه که این سوالات در حیطه دانشکده معنا پیدا میکنه و در صنعت بی معناست. شما قبل از ارسال پست، باید از خودتون می پرسیدید: "اگر قرار بود متغیر const قابل تغییر باشه، پس دیگه برای چی اصلا چیزی به اسم const بوجود اومده؟" وقتی متغیری رو const تعریف می کنید، دارید به Compiler می گید که اجازه داره اونو به بهترین شکل ممکن هنگام کامپایل کردن برنامه، Optimize کنه. بدین ترتیب، تغییر یک متغیر const در runtime میتونه باعث "رفتاری تعریف نشده" بشه، چون با حقه مقدار مربوطه تغییر پیدا میکنه و برنامه Compile شده از این تغییر آگاه نمیشه. با این حال، پاسخی که دارم بهتون میدم فقط بین خودمون میمونه و هرگز از اون در دنیای واقعی نباید استفاده کنید.

تابع زیر رو در نظر بگیرید:


void MyFunction()
{
const int val = 10;
int *p = (int *)&val;

//val == 10
*p = 20;

//val == 20
}
توی این تابع، ابتدا یک متغیر const int تعریف می کنم، و سپس به کمک Pointer ای به اسم p، مقدار 10 رو تغییر میدم. اگر اشتباه نکنم و درست بخاطرم مونده باشه، همین کار رو شما میتونید در Compiler های قدیمی و با متغیرهای const ای که بصورت Global تعریف شده اند نیز انجام بدید (تکرار میکنم، دقیق خاطرم نیست که این کار شدنی بود یا نه). با این حال، اگر در کامپایلری مثل VS2010، متغیر val رو بصورت Global تعریف کنید، اونوقت خط *p = 20 با خطا مواجه میشه. اما دلیل این خطا چیه؟ تو مرحله اول متغیر local در Stack تعریف شده، که حافظه ای خوندنی - نوشتنی هستش. اما متغیر Global ما، در حافظه فقط خوندنی نوشته شده، در نتیجه تلاش برای تغییر اون با مشکل مواجه میشه. البته همه این داستانهایی که گفتم رو میشه با یکی دو سوئیچی که به Compiler میدیم تغییر داد، اما حقیقتش این کار اونقدر بیمعناست که بیشتر از این در موردش صحبت نمیکنم.

اما سوال دوم، حذف و تغییر متغیری که حافظه اش بصورت داینامیک Allocate نشده باشه... برای اینکار، می تونید متغیر مربوطه رو در Stack بگیرید:


void MyFunction()
{
//p is undefined here...
{
char *p = (char *)_alloca(20);
//p is automatically released...
}
//p is undefined here...
}
دقت کنید، اینجا با استفاده از _alloca من حافظه ای به اندازه 20 بایت میگیرم. به اون {} ها دقت کنید. p فقط در block درونی تعریف شده، و وقتی اجرا از اون block خارج بشه، حافظه بطور خودکار به سیستم برمیگرده. البته هنگام استفاده از _alloca باید حواستون به Optimization هایی که Compiler انجام میده باشه، چون ممکنه براحتی Stack Overflow رخ بده (یکی از جاهایی که این اتفاق ممکنه بیفته وقتی هستش که Compiler تابعی رو Inline در نظر بگیره و شما در اون تابع از این روش استفاده کرده باشید و ...) اما در کل، سوال شما رو میشه به نوع دیگه ای هم پاسخ داد. کد زیر رو در نظر بگیرید:



void MyFunction1()
{
//allocate some memory...
}
اینجا، تا وقتی MyFunction1 صدا زده نشده، Memory ای هم از سیستم گرفته نمیشه و متغیر نیز وجود نخواهد داشت. بنابراین میشه اینطور به مساله نگاه کرد که فقط کافیه عملیات مورد نظر رو که به تخصیص حافظه نیاز دارن در یک تابع نوشت و تا وقتی تابع مورد نظر در runtime فراخوانی نشده، دیگه نیازی نیست تا نگران (بقول شما) "حذف کردن" یا تعریف کردن اون متغیر و حافظه باشیم.

موفق باشید.

پاورقی: استفاده از _alloca دردسرهای دیگه ای هم داره، که با جستجویی روی اینترنت میتونید به اونها پی ببرید، اما خوب، اگر خوب ازش استفاده بشه، بعضی وقتها کد رو بطرز چشمگیری خوانا میکنه و حتی میتونه تاثیر خوبی روی Performance برنامه (در اون Block خاص) نیز داشته باشه.