نمایش نتایج 1 تا 20 از 20

نام تاپیک: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

  1. #1

    سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    سال نو مبارک ...
    سلام
    همون طور که می دونید به طور کلی حافظه به سه بخش تقسیم می شه
    بخش اول همون کد کامپایل شده برنامه (text (code) segment)
    بخش دوم حافظه متغیرهای اتوماتیک، توابع و یا دیتا (stack segment)
    بخش سوم حافظه داینامیک برنامه (heap segment)

    HeapAndStack.png

    ----------------------------------------------------------------------------------------
    اصلاح مطلب بالا : طبق این لینک و بحث هایی که در ادامه شد

    Program memory
    The computer program memory is organized into the following


    Data Segment :: Data + BSS + Heap

    Stack

    Code segment


    --------------------------------------------------------------------------------------------------------
    سوال اول و مهمترین سوال من) متغیرها، اشیاء و توابعی که به صورت ( global و به خصوص static) تعریف می شوند، فکر می کنم در بخش دوم یعنی stack ذخیره می شن، حالا می خوام بدونم این ذخیره سازی به چه نحوی صورت می گیره، یعنی یک متغیر سراسری (global یا یک متغیر static) پس از فراخوانی تابع اصلی برنامه (main) توسط سیستم و قرار گرفتن main در stack ، کجا و به چه نحوی ذخیره می شه؟(static stack storage)
    سوال دوم) حافظه ای که به صورت استاتیک(static) و یا سراسری(global) دریافت شده رو، اگر بخوایم در طول برنامه به سیستم برگردونیم باید چه طوری عمل کنیم؟اصلا امکانش هست؟
    سوال سوم) اختصاص و حذف حافظه داینامیک فقط و فقط توسط new , delete صورت خواهد پذیرفت؟بهتر بگم چگونه بدون استفاده از new میشه چیزی رو در heap قرار داد مانند تابع calcSize در تصویر بالا؟
    سوال چهارم) متغیرها، اشیاء و توابع ثابت (const) هم در بخش stack ذخیره می شوند؟ و آیا مشابه متغیرهای اتوماتیک با آن ها برخورد خواهد شد؟
    سوال پنجم) حتما اولین چیزی که در حافظه قرار می گیرد و آخرین چیزی که از حافظه حذف می شه تابع main است؟ (LIFO-Last In First Out) (یعنی حتی متغیر های سراسری هم بعد از main در حافظه قرار می گیرند و خارج می شوند) و اما در آخر فراخوانی و نگهداری دائم تابع main در برنامه توسط چه بخشی صورت می گیرد؟کامپایلر؟
    تشکر
    آخرین ویرایش به وسیله chikar : یک شنبه 02 فروردین 1394 در 20:54 عصر

  2. #2

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    سلام
    در این تاپیک در باره همین موضوع بحث شده:
    https://barnamenevis.org/showthread.php?465559

    متغیرهای static (مدت حافظه اونها static باشه) در پشته ذخیره نمیشن بلکه به همراه heap در قسمت data segment قرار دارند
    در مورد const هم بسته به اینکه اتوماتیک یا استاتیک یا داینامیک باشه قضیه اونها فرق می کنه که به ترتیب در stack یا data segment یا heap قرار بگیره
    همچنین در اون تاپیک در مورد بهینه سازی const صحبت شده که ممکنه در قسمت text قرار بگیره
    ممکنه یک متغیر static که گلوبال هم باشه قبل از ورود به تابع main مقدار دهی اولیه یا Initialize بشه که این بستگی به پیاده سازی داره و با فراخوانی return از بین می ره

    حافظه پویا غیر از new با تابعهایی مثل malloc هم میشه رزرو کرد

  3. #3

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک
    سلام


    متغیرهای static (مدت حافظه اونها static باشه) در پشته ذخیره نمیشن بلکه به همراه heap در قسمت data segment قرار دارندممکنه یک متغیر static که گلوبال هم باشه قبل از ورود به تابع main مقدار دهی اولیه یا Initialize بشه که این بستگی به پیاده سازی داره و با فراخوانی return از بین می ره

    منظورتون رو از متغیرهای static (مدت حافظه اونها static باشه) رو درست متوجه نشدم، یعنی می شه متغیرهای استاتیکی ساخت که مدت حافظشون استاتیک نباشه؟یعنی چطوری؟
    اگر متغیرهای استاتیک در پشته ذخیره نمی شن، پس مفهوم static stack storage چی میشه؟

    مگر غیر از این نیست که تفاوت یک متغیر گلوبال و استاتیک در حوزه دسترسی(scope) اون هاست، آیا تفاوت دیگه ای هم دارند؟
    Data Segment :: Data + BSS + Heap
    در Data فقط این مقادیر ذخیره می شه (global and static variables که مقدار غیر از صفر دارند یا Initialize شده باشن)؟ در BSS هم متغیر استاتیک یا گلوبالی که مقدار صفر دارند یا Initialize نشده باشند، درسته ؟
    حافظه ای که متغیرهای گلوبال و استاتیک گرفتند رو در طول برنامه می شه پس گرفت؟


    ممنون از پاسختون و سال نو شما مبارک...
    آخرین ویرایش به وسیله chikar : شنبه 01 فروردین 1394 در 00:58 صبح

  4. #4

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    اولا من هم سال جدید را به شما تبریک می گم
    منظورم از مدت حافظه استاتیک این بود که ممکنه مثلا ما برای تعریف یک متغیر از کلمه کلیدی static استفاده نکنیم ولی مدت حافظه اون استاتیک باشه. مثل متغیرهای سراسری که تعریف می کنیم
    والا مفهوم static stack storage را نمیدونم چیه. از منبع خاصی نقل می کنید؟
    ببینید کلمه static و سایر کلماتی که برای مشخص کردن کلاس حافظه به کار می رن دو تا چیز با هاشون تعیین میشه:
    1- مدت حافظه
    2- لینکیج یا پیوند
    یک متغیر که داخل یک تابع با کلمه کلیدی static تعریف شده باشه ( متغیر محلی باشه)، مدت حافظه اون static ولی بدون لینکیج هست
    یک متغیری که در فضای نام سراسری و بدون کلمه کلیدی static یا کلمه های دیگر تعریف شده باشه، مدت حافظه اون static و لینکیج اون خارجی هست
    یک متغیری که در فضای نام سراسری و با کلمه کلیدی static تعریف شده باشه، مدت حافظه اون static و لینکیج اون داخلی هست
    البته اینها در تاپیک زیر هم مطرح شده:
    https://barnamenevis.org/showthread.php?448698
    نکته ای که در مورد datat segment اشاره کردید درسته این مطلب هم به صورت نمودار
    این مطلب هم در خصوص فایلهای اجرایی ویندوز در این موضوع صحبت کرده
    متغیرهایی که مدت حافظه استاتیک دارند تا پایان برنامه پابرجا هستند و نمیشه حافظه را از آنها گرفت
    هر روزتان نوروز، نوروزتان پیروز...

  5. #5

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک
    والا مفهوم static stack storage را نمیدونم چیه. از منبع خاصی نقل می کنید؟
    بله در این لینک، یک مثال ساده زده و متغیر گلوبال x رو از نوع static stack storage تعریف کرده
    در همون لینک فوق گفته
    If the main() function calls another function in the program, for example calcSize(), additional storage will be allocated for the variables in calcSize(). This storage will be allocated in the heap memory segment
    When the calcSize() function returns the value, the space for its local variables at heap is then deallocated and heap clears to be available for other functions
    یعنی علت دوام توابع یا متغیرهایی که در main تعریف می شه این هست که پس از تعریف در main وارد حافظه heap می شن و تا زمان return اونجا باقی می مونند؟
    همچنین آیا استفاده از malloc رو توصیه می کنید؟ حافظه اختصاص داده شده توسط malloc چگونه پس گرفته خواهد شد؟
    یه سوال دیگه هم دارم، چه عاملی باعث فراخوانی main و نگهداری دائم این تابع در stack در تمام طول برنامه می شه؟

    باز هم ممنون از پاسخ خوبتون و براتون سال زیبایی رو آرزو دارم / تشکر ...
    آخرین ویرایش به وسیله chikar : شنبه 01 فروردین 1394 در 08:58 صبح

  6. #6

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    متاسفانه مطالب سایت مذکور اشتباهه
    گفته متغیرهای محلی در heap قرار می گیرند که اشتباهه
    خودمون هم می تونیم تست کنیم آدرس متغیر ها را می گیریم ببینیم کجا هستند



    #include <stdio.h>
    #include <stdlib.h>

    int global;
    int calcSize(int input)
    {
    int a = input;
    int b = a *5;

    printf("Address of local variable \"a\" in \"calcSize\" is %p\n", &a);
    printf("Address of local variable \"b\" in \"calcSize\" is %p\n", &b);
    return b;
    }

    int main ()
    {
    int local = 5;
    void *p = malloc(128);

    printf ("Address of main is %p\n", main);
    printf ("Address of global is %p\n", &global);
    printf ("Address of local is %p\n", &local);
    printf ("Address of p is %p\n", p);

    int size = calcSize(10);
    return 0;
    }

    همون طور که مشاهده می کنید متغیر p که آدرس موجود در heap را نشون میده و متغیرهای a و b در stack قرار گرفته اند همون طور که local در stack قرار گرفته
    لطفا این pdf را مطالعه کنید که همین مطلب را توضیح داده
    malloc برای برنامه های زبان c استفاده می شه همون new استفاده ازش راحت تره و بهتره
    با تابع free هم میشه حافظه ای که با malloc اشغال شده آزاد کرد
    اینکه مثلا با دابل کلیک یک برنامه چه اتفاقی می افته مثلا در لینوکس می تونید این مطلب را مطالعه کنید
    http://dbp-consulting.com/tutorials/...amStartup.html

    سال خوبی داشته باشید

  7. #7

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک
    خودمون هم می تونیم تست کنیم آدرس متغیر ها را می گیریم ببینیم کجا هستند
    فکر می کنم این بحث خیلی طولانی شد، امیدوارم خسته تون نکرده باشم
    من به کد بالا یه چیزایی اضافه کردم که مشخص است و خروجی گرفتم به شکل زیر

    Address of main is 00FE1000
    Address of global is 00FE3000
    Address of static int static_var; in main is 00FE3038

    Address of local is 0015FB48

    Address of p is 00A1E930
    Address of int *pointer=new int; is 00A1D990
    Address of int *ps; is 00A1E9E0

    Address of local variable "a" in "calcSize" is 0015FB4C
    Address of local variable "b" in "calcSize" is 0015FB50
    با توجه به کد بالا main در text code قرار میگیره
    متغیرهای global,static_var در دیتا سگمنت ذخیره می شن
    متغیرهای local,a,b در stack قرار می گیرند
    و همچنین p,pointer,ps در heap قرار می گیرند
    آیا این مساله درسته؟

    اگر درسته چرا اشاره گری مثل ps که به جایی اشاره نداره و با new هم مقدار دهی نشده در heap قرار می گیره؟

    باز هم تشکر فراوان از شما...

  8. #8

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    به نظرم بحث خوبیه

    int main()
    {
    int* a;
    a = new int[10];
    }

    ببینید a یک متغیر هست از نوع اشاره گر به int که وقتی در ابتدا تعریف میشه یک مقدار نامعلوم بهش تعلق می گیره یعنی با یک مقدار نامعلوم مقدار دهی اولیه می شه
    ممکنه این عدد 87 یا 0 یا 987457 یا عدد دیگه ای باشه
    مکان a در stack هست و مقدار جایی که در stack اشغال می کنه بسته به نوع سیستم که 32 یا 64 بیتی باشه 4 یا 8 بایت جا می گیره
    با در نظر گرفتن اینکه سایز int برابر 4 هست وقتی [new int[10 اجرا بشه یک شی به اندازه 10 ضرب در 4 یعنی 40 بایت در heapایجاد میشه و آدرس اون در a قرار می گیره
    a کماکان در stack قرار داره اما اکنون به یک جای منطقی اشاره می کنه
    بنابراین توصیه می شه هر وقت بخواهیم یک اشاره گر را تعریف کنیم حتما اون را مقدار دهی با NULL کنیم که از خطاهای احتمالی بعدی هم جلوگیری بشه

    int* a = nullptr;
    a = new int[10];

  9. #9

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک

    int main()
    {
    int* a;
    a = new int[10];
    }

    با در نظر گرفتن اینکه سایز int برابر 4 هست وقتی [new int[10 اجرا بشه یک شی به اندازه 10 ضرب در 4 یعنی 40 بایت در heapایجاد میشه و آدرس اون در a قرار می گیره
    a کماکان در stack قرار داره اما اکنون به یک جای منطقی اشاره می کنه
    اول بپرسم طبقه بندی که در بالا شده بود درست بود؟

    فکر کنم یه کم گیج شدم، فکر می کردم خود a هم در heap ذخیره می شه نه فقط حافظه اختصاص داده شده به اون مثلا [new int[10
    مثالی که زدید فقط در بلوک تابع main که عمر دائم داره صدق می کنه؟ چون
    مگه متغیری مثل a اگر که در stack قرار داده بشه، عمرش به اندازه بلوکی که داخلش هست، نیست؟ پس باید a بعد از اتمام بلوکی که تو اون تعریف شده از استک حذف بشه (LIFO-Last In First Out)، (مگه اینکه a در heap یا main قرار گرفته شده باشه) و در صورت حذف a از استک که آدرس این فضا رو داشت هم دیگه فضای 40 بایتی اون در heap به چه درد می خوره !؟
    یا نکنه صرفاً اشاره کردن a در استک به یک جای منطقی مثل حافظه اختصاص داده شده به اون در heap اون رو از حذف شدن از استک مصون می کنه؟

    باز هم تشکر ...

  10. #10

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    طبقه بندی درست بود
    حالا اگه a در یک تابع غیر از main بود وقتی که تابع تموم می شد اگه ما اون را free یا delete نمی کردیم
    طبیعتا اشاره گر از بین می رفت اما
    اون حافظه 40 بایتی به صورت بلا استفاده در heap تا انتهای برنامه باقی می موند که بهش می گن نشت حافظه یا memory leak

  11. #11

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک
    حیفم میاد این بحث خوب رو با وجودی که هنوز سوالاتی وجود داره تموم کنم ...
    فکر می کنم مشابه stack که با سرریزی (stackoverflow) می تونه همراه باشه، heap هم می تونه سر ریز بشه یه مثال می زنم که فکر کنم هم heap سر ریز شه و هم stack، البته فکر می کنم با توجه به اینکه stack حافظه کمتری رو در اختیار داره، قبل از اینکه heap سر ریز بشه برنامه رو با مشکل مواجه کنه مثل ختم برنامه و اما مثال

    void Overflow()
    {
    int local = 0;
    long long *x = new long long[10000];
    std::cout << " x is: " << x <<"\n" << " local is: " << &local << "\n";
    Overflow();
    }


    int main(int argc, char *argv[])
    {
    Overflow();
    return 0;
    }


    بخش کوچکی از خروجی

    x is: 00417158
    local is: 0022CBA8
    x is: 00640048
    local is: 0022CB98
    x is: 006538D0
    local is: 0022CB88
    x is: 00667158
    local is: 0022CB78
    x is: 01BE0048
    local is: 0022CB68
    x is: 01BF38D0
    local is: 0022CB

    آیا امکان مشاهده فضای heap و stack با برنامه نویسی در طول برنامه وجود داره؟ از این جهت می پرسم که آیا امکان داره بشه این فضا ها رو طوری مدیریت کرد که مثلا قبل از overflow مثلا در مثال فوق از تابع برنامه خارج بشه و stack رو خالی کنه؟
    آیا امکانش هست که فضای بیشتری رو از ram برای stack و heap برنامه مون از سیستم کاربر بگیریم؟
    آیا میشه از ram + hard disk به صورت share استفاده کرد و میزان حافظه که در اختیارمون هست رو افزایش داد؟
    آیا مقادیر گلوبال و استاتیک هم می تونند overfliw شوند؟ اگه آره به چه شکلی؟
    آخرین ویرایش به وسیله chikar : یک شنبه 02 فروردین 1394 در 19:05 عصر

  12. #12

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک
    یه سوال دیگه هم دارم که مربوط به مبحث قبلی است
    متغیرهای محلی که درون تابع main تعریف می شن، درون استک قرار میگیرند، داخل استک هم که آخه چیزی دوام نداره، و مدام push و pop میشه، پس این متغیرها چطوری در تمام طول برنامه زنده اند و وجود دارند؟
    با وجودی که خود main در بخش text code قرار می گیره پس برای دوام اون متغیرها و توابع محلی، باید کنار main قرار گرفته شده باشند ولی تو مثالی که خودتون زدید دیدیم که مکان متغیرهای محلی که در main هستند در استک قرار داره و با مکان خود main تفاوت دارند!

    مرسی ...

  13. #13

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    در زمینه heap ما buffer overflow داریم که البته به این معنا هست که ما بخواهیم به فضایی خارج از فضای اشغال شده دسترسی پیدا کنیم
    اما new اگه نتونه فضای لازم را تخصیص بده null بر می گردونه
    امکان مشاهده حافظه وجود داره البته از طریق تابعهای api دلیلش را متوجه نشدم که چرا این کار را انجام بدیم
    ضمنا هنگام کامپایل می تونیم به کامپایلر بگیم که فضای استک را افزایش بده
    می شه از فضای هارد به عنوان حافظه استفاده کرد memory mapped file
    دستورالعملهای برنامه به همراه داده های استاتیک موقعی که برنامه کامپایل میشه در فایل اجرایی در دیسک ذخیره میشن
    ضمنا مثلا در ویندوز هم سایز فایل اجرایی محدودیت داره که از یک اندازه ای نباید بزرگتر بشه
    بنابراین ممکنه اگه سایز متغیر استاتیک زیاد باشه برنامه نتونه اجرا بشه تا حالا امتحان نکردم

  14. #14

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط chikar مشاهده تاپیک
    یه سوال دیگه هم دارم که مربوط به مبحث قبلی است
    متغیرهای محلی که درون تابع main تعریف می شن، درون استک قرار میگیرند، داخل استک هم که آخه چیزی دوام نداره، و مدام push و pop میشه، پس این متغیرها چطوری در تمام طول برنامه زنده اند و وجود دارند؟
    با وجودی که خود main در بخش text code قرار می گیره پس برای دوام اون متغیرها و توابع محلی، باید کنار main قرار گرفته شده باشند ولی تو مثالی که خودتون زدید دیدیم که مکان متغیرهای محلی که در main هستند در استک قرار داره و با مکان خود main تفاوت دارند!

    مرسی ...
    این متغیرهایی که در استک هستند را می شه با آدرس بهشون دسترسی پیدا کرد یعنی لزوما عنصری که در بالا هست تنها عنصری نیست که بشه بهش دسترسی پیدا کرد بلکه عناصر دیگه هم با آدرس، قابل دسترسی هستند و ضمانت شده متغیرهای محلی اتوماتیک برعکس ترتیبی که ایجاد میشن در پایان تخریب میشن
    خود آدرس main که در استک نیست فقط متغیرهای محلی و پارامترهای اون در استک هستند
    در واقع آدرس main جایی هست که دستورالعملها شروع میشه
    آخرین ویرایش به وسیله rahnema1 : دوشنبه 03 فروردین 1394 در 00:45 صبح

  15. #15

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول نوشته شده توسط rahnema1 مشاهده تاپیک
    ممنون از پاسخ ها تون

    نقل قول : در زمینه heap ما buffer overflow داریم که البته به این معنا هست که ما بخواهیم به فضایی خارج از فضای اشغال شده دسترسی پیدا کنیم.
    ج : این buffer overflow به طور خودکار زمانی که heap پر بشه، می تونه مورد استفاده قرار بگیره مثلا با برنامه نویسی؟ اندازه اش چقدر می تونه باشه؟

    نقل قول : امکان مشاهده حافظه وجود داره البته از طریق تابعهای api دلیلش را متوجه نشدم که چرا این کار را انجام بدیم
    ج : پیش بینی کنیم اگر استک داره پر می شه، بهتر مدیریتش کنیم مثلا بگیم فضای استک رو افزایش بده
    نقل قول: ضمنا هنگام کامپایل می تونیم به کامپایلر بگیم که فضای استک را افزایش بده
    ج : میشه بفرمایید چطوری؟
    نقل قول: می شه از فضای هارد به عنوان حافظه استفاده کرد memory mapped file
    ج : سرعت برنامه خیلی کاهش پیدا نمی کنه؟
    آخرین ویرایش به وسیله chikar : دوشنبه 03 فروردین 1394 در 12:54 عصر

  16. #16

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    یه سوال دیگه : اگر یه متغیری به این صورت باشه:

    extern int a = 10;
    int main
    {
    //.....
    }

    حالا اگز از a بخوایم تو کلاس های myclass1 و myclass2 استفاده کنیم، اولا مشابهی که a رو در بالا تعریف کردیم باید تو اون فایل ها هم تعریف کنیم فقط بدون مقدار دهی اولیه
    اصلا چرا باید تو فایل های دیگه دوباره a رو تعریف کنیم ، یعنی extern int a مگه a یه بار تعریف و مقدار دهی نشده؟ اونم حتما با extern ؟
    سوال؟ یعنی فقط تو کل پروژه یکبار می شه به صورت سراسری a رو مقدار دهی کرد؟
    برای استفاده از a در تمام فایل ها باید هر بار a رو به صورت سراسری و با کلمه extern تو همه فایل ها بیاریم؟ چون در غیر اینصورت خطا می ده که a هم اکنون در فایل فلان تعریف شده!اگر هم با استاتیک بیاد عملا یه a دیگه تعریف شده تو اون فایل!
    مرسی ...
    آخرین ویرایش به وسیله chikar : دوشنبه 03 فروردین 1394 در 13:40 عصر

  17. #17

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    نقل قول : این buffer overflow به طور خودکار زمانی که heap پر بشه، می تونه مورد استفاده قرار بگیره مثلا با برنامه نویسی؟ اندازه اش چقدر می تونه باشه؟
    ج: اینجا overflow به این معنا نیست که heap پر شده مثلا من یک حافظه به طول 10 بایت اشغال کردم و بخواهم در آدرسی که بعد از خانه انتهایی آرایه دسترسی پیدا کنم بهش میگن buffer overflow که این کار اشتباهه
    نقل قول: بگیم فضای استک رو افزایش بده
    ج: همون بهتر که هر کاری می خواهیم بکنیم با همون حافظه heap بکنیم.
    نقل قول : میشه بفرمایید چطوری؟
    ج: برای ویژوال استادیو در قسمت تنظیمات linker گزینه Stack Reserve Size را تغییر بدید یا:
    https://msdn.microsoft.com/en-us/library/tdkhxaks.aspx
    برای gcc هم توی این لینک توضیح داده
    نقل قول : سرعت برنامه خیلی کاهش پیدا نمی کنه؟
    ج: خب معلومه چون سرعت هارد خیلی کمتره

  18. #18

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    ببیند ما دو مفهوم اعلان یا declaration و مفهوم تعریف definition مواجه هستیم
    declaration صرفا یک اسم را به همراه ویژگیهاش برای ما معرفی می کنه اما تعریف باعث میشه یک شیء ایجاد بشه و حافظه بهش اختصاص داده بشه
    همیشه اعلان مساوی با تعریفه مگر در چند مورد که یکی از اونها وقتیه که هنگام اعلان از extern استفاده کنیم و مقداردهای اولیه هم انجام نشه
    توی این مثال که شما زدید یک متغیر به نام a «تعریف» کردید و اعلان صرف نیست چون مقدار دهی اولیه شده و فضای حافظه بهش اختصاص داده شده
    به عبارت دیگه اینجا extern کار خاصی انجام نمیده و لینکیج a خارجی و مدت حافظه اش static هست
    حالا این پروژه ای که ایجاد کردید نمیدونم ساختارش چه جوریه
    اگه می خواهید اون فایلها را include کنید که دیگه لازم نیست متغیرها تعریف بشن
    اما اگه اونها در واحدهای ترجمه متفاوت باشن لازمه که ما وقتی می خواهیم از اونها استفاده کنیم با extern یک متغیر اعلان کنیم که بگیم این متغیر لینکیج خارجی داره و مثلا می خواهد از یک واحد ترجمه دیگه متغیری به همین نام را بخونه
    نقل قول: سوال؟ یعنی فقط تو کل پروژه یکبار می شه به صورت سراسری a رو مقدار دهی کرد؟
    تعریف متغیر فقط یک بار هست اما اعلان را به تعداد دلخواه میشه انجام داد
    یک تاپیک که در پست 4 معرفی کردم داخلش همین مطالب هست

  19. #19

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    سلام
    چرا وقتی که فایل exe یک برنامه نوشته شده با زبان سی را چندین بار بصورت هم زمان اجرا میکنیم ، علیرغم اینکه برنامه هربار بطور مستقل از برنامه های قبلی اجرا میشه ، اما باز هم آدرس متغیرها در حافظه تغییری نمیکنه ؟
    مگر نباید برای هر برنامه فضای جداگانه ای از حافظه تخصیص داده بشه ؟
    چطور ممکنه آدرس متغیر همون باشه اما هم زمان سه مقدار مختلف داشته باشه ؟
    همونطور که در تصویر هم دیده میشه هر سه برنامه درحال اجرا هستش و بعلت وجود getch برنامه هنوز خاتمه پیدا نکرده بنابراین حافظه تخصیص داده شده به متغیر هنوز آزاد نشده .
    کسی میتونه دلیل یکسان بودن آدرس ها رو توضیح بده ؟

    ویرایش : امروز همین تست را در سیستم عامل لینوکس (فدورا) انجام دادم . در لینوکس و ویندوز از یک کامپایلر استفاده کردم (gcc)
    در لینوکس در هر بار اجرا آدرس حافظه تغییر میکنه . وقتی هم که چند بار بطور هم زمان این فایل رو اجرا می کنم در هر کدومش آدرس جداگانه ای میگیره
    پس چرا در ویندوز تحت هیچ شرایطی آدرس متغیر در حافظه تغییر نمیکنه ؟


    #include <stdio.h>

    int main()
    {
    int i;
    printf("Enter integer Numbet : ");
    scanf("%d",&i);
    printf("\nNumber -------> %d\n",i);
    printf("Address -------> %0X\n",&i);
    getch();
    return 0;
    }





    آخرین ویرایش به وسیله hpcompaq6720s : چهارشنبه 02 آبان 1397 در 07:57 صبح

  20. #20

    نقل قول: سوال در مورد مفاهیم حافظه text code,stack,heap, static/global

    Memory management is the heart of operating systems; it is crucial for both programming and system administration. In the next few posts I'll cover memory with an eye towards practical aspects, but without shying away from internals. While the concepts are generic, examples are mostly from Linux and Windows on 32-bit x86. This first post describes how programs are laid out in memory.

    Each process in a multi-tasking OS runs in its own memory sandbox. This sandbox is the virtual address space, which in 32-bit mode is always a 4GB block of memory addresses. These virtual addresses are mapped to physical memory by page tables, which are maintained by the operating system kernel and consulted by the processor. Each process has its own set of page tables, but there is a catch. Once virtual addresses are enabled, they apply to all software running in the machine, including the kernel itself. Thus a portion of the virtual address space must be reserved to the kernel:

    kernelUserMemorySplit.png

    This does not mean the kernel uses that much physical memory, only that it has that portion of address space available to map whatever physical memory it wishes. Kernel space is flagged in the page tables as exclusive to privileged code (ring 2 or lower), hence a page fault is triggered if user-mode programs try to touch it. In Linux, kernel space is constantly present and maps the same physical memory in all processes. Kernel code and data are always addressable, ready to handle interrupts or system calls at any time. By contrast, the mapping for the user-mode portion of the address space changes whenever a process switch happens:

    virtualMemoryInProcessSwitch.png

    Blue regions represent virtual addresses that are mapped to physical memory, whereas white regions are unmapped. In the example above, Firefox has used far more of its virtual address space due to its legendary memory hunger. The distinct bands in the address space correspond to memory segments like the heap, stack, and so on. Keep in mind these segments are simply a range of memory addresses and have nothing to do with Intel-style segments. Anyway, here is the standard segment layout in a Linux process:

    linuxFlexibleAddressSpaceLayout.png

    When computing was happy and safe and cuddly, the starting virtual addresses for the segments shown above were exactly the same for nearly every process in a machine. This made it easy to exploit security vulnerabilities remotely. An exploit often needs to reference absolute memory locations: an address on the stack, the address for a library function, etc. Remote attackers must choose this location blindly, counting on the fact that address spaces are all the same. When they are, people get pwned. Thus address space randomization has become popular. Linux randomizes the stack, memory mapping segment, and heap by adding offsets to their starting addresses. Unfortunately the 32-bit address space is pretty tight, leaving little room for randomization and hampering its effectiveness.

    The topmost segment in the process address space is the stack, which stores local variables and function parameters in most programming languages. Calling a method or function pushes a new stack frame onto the stack. The stack frame is destroyed when the function returns. This simple design, possible because the data obeys strict LIFO order, means that no complex data structure is needed to track stack contents - a simple pointer to the top of the stack will do. Pushing and popping are thus very fast and deterministic. Also, the constant reuse of stack regions tends to keep active stack memory in the cpu caches, speeding up access. Each thread in a process gets its own stack.

    It is possible to exhaust the area mapping the stack by pushing more data than it can fit. This triggers a page fault that is handled in Linux by expand_stack(), which in turn calls acct_stack_growth() to check whether it's appropriate to grow the stack. If the stack size is below RLIMIT_STACK (usually 8MB), then normally the stack grows and the program continues merrily, unaware of what just happened. This is the normal mechanism whereby stack size adjusts to demand. However, if the maximum stack size has been reached, we have a stack overflow and the program receives a Segmentation Fault. While the mapped stack area expands to meet demand, it does not shrink back when the stack gets smaller. Like the federal budget, it only expands.

    Dynamic stack growth is the only situation in which access to an unmapped memory region, shown in white above, might be valid. Any other access to unmapped memory triggers a page fault that results in a Segmentation Fault. Some mapped areas are read-only, hence write attempts to these areas also lead to segfaults.

    Below the stack, we have the memory mapping segment. Here the kernel maps contents of files directly to memory. Any application can ask for such a mapping via the Linux mmap() system call (implementation) or CreateFileMapping() / MapViewOfFile() in Windows. Memory mapping is a convenient and high-performance way to do file I/O, so it is used for loading dynamic libraries. It is also possible to create an anonymous memory mapping that does not correspond to any files, being used instead for program data. In Linux, if you request a large block of memory via malloc(), the C library will create such an anonymous mapping instead of using heap memory. 'Large' means larger than MMAP_THRESHOLD bytes, 128 kB by default and adjustable via mallopt().

    Speaking of the heap, it comes next in our plunge into address space. The heap provides runtime memory allocation, like the stack, meant for data that must outlive the function doing the allocation, unlike the stack. Most languages provide heap management to programs. Satisfying memory requests is thus a joint affair between the language runtime and the kernel. In C, the interface to heap allocation is malloc() and friends, whereas in a garbage-collected language like C#‎ the interface is the new keyword.

    If there is enough space in the heap to satisfy a memory request, it can be handled by the language runtime without kernel involvement. Otherwise the heap is enlarged via the brk() system call (implementation) to make room for the requested block. Heap management is complex, requiring sophisticated algorithms that strive for speed and efficient memory usage in the face of our programs' chaotic allocation patterns. The time needed to service a heap request can vary substantially. Real-time systems have special-purpose allocators to deal with this problem. Heaps also become fragmented, shown below:

    fragmentedHeap.png

    Finally, we get to the lowest segments of memory: BSS, data, and program text. Both BSS and data store contents for static (global) variables in C. The difference is that BSS stores the contents of uninitialized static variables, whose values are not set by the programmer in source code. The BSS memory area is anonymous: it does not map any file. If you say static int cntActiveUsers, the contents of cntActiveUsers live in the BSS.

    The data segment, on the other hand, holds the contents for static variables initialized in source code. This memory area is not anonymous. It maps the part of the program's binary image that contains the initial static values given in source code. So if you say static int cntWorkerBees = 10, the contents of cntWorkerBees live in the data segment and start out as 10. Even though the data segment maps a file, it is a private memory mapping, which means that updates to memory are not reflected in the underlying file. This must be the case, otherwise assignments to global variables would change your on-disk binary image. Inconceivable!

    The data example in the diagram is trickier because it uses a pointer. In that case, the contents of pointer gonzo - a 4-byte memory address - live in the data segment. The actual string it points to does not, however. The string lives in the text segment, which is read-only and stores all of your code in addition to tidbits like string literals. The text segment also maps your binary file in memory, but writes to this area earn your program a Segmentation Fault. This helps prevent pointer bugs, though not as effectively as avoiding C in the first place. Here's a diagram showing these segments and our example variables:

    mappingBinaryImage.png

    You can examine the memory areas in a Linux process by reading the file /proc/pid_of_process/maps. Keep in mind that a segment may contain many areas. For example, each memory mapped file normally has its own area in the mmap segment, and dynamic libraries have extra areas similar to BSS and data. The next post will clarify what 'area' really means. Also, sometimes people say "data segment" meaning all of data + bss + heap.

    You can examine binary images using the nm and objdump commands to display symbols, their addresses, segments, and so on. Finally, the virtual address layout described above is the "flexible" layout in Linux, which has been the default for a few years. It assumes that we have a value for RLIMIT_STACK. When that's not the case, Linux reverts back to the "classic" layout shown below:

    linuxClassicAddressSpaceLayout.png

    That's it for virtual address space layout. The next post discusses how the kernel keeps track of these memory areas. Coming up we'll look at memory mapping, how file reading and writing ties into all this and what memory usage figures mean.

تاپیک های مشابه

  1. مبتدی: سوال در مورد دسترسی خاصیت text سلول های جداول در stimulsoft reports از طریق کد C#‎
    نوشته شده توسط hmdhamed در بخش ابزارهای گزارش سازی
    پاسخ: 7
    آخرین پست: سه شنبه 08 فروردین 1391, 22:43 عصر
  2. سوال در مورد مقدار حافظه اشکالی ورودی از صفحه کلید
    نوشته شده توسط xman_dj در بخش برنامه نویسی با زبان C و ++C
    پاسخ: 5
    آخرین پست: سه شنبه 06 اردیبهشت 1390, 12:41 عصر
  3. سوال در مورد محدود کردن Text box ...!
    نوشته شده توسط sam_fisher_440 در بخش برنامه نویسی در 6 VB
    پاسخ: 6
    آخرین پست: شنبه 23 مرداد 1389, 17:38 عصر
  4. سوال در مورد مفاهیم OOP
    نوشته شده توسط BestLover در بخش VB.NET
    پاسخ: 1
    آخرین پست: شنبه 21 دی 1387, 15:49 عصر
  5. سوال در مورد فیلد نوع Text
    نوشته شده توسط mehdi_moosavi در بخش SQL Server
    پاسخ: 1
    آخرین پست: چهارشنبه 01 تیر 1384, 19:59 عصر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •