Резервирует ли компилятор память для самого большого блока кода или всех блоков в C? - PullRequest
0 голосов
/ 05 февраля 2019

Распределяет ли компилятор C всю память, необходимую перед запуском программы, или он выделяет память для самого большого блока памяти?В обоих случаях я спрашиваю о статически выделенной памяти, я понимаю, что при динамическом выделении памяти память запрашивается во время выполнения.

См. Ниже код

    #include <stdio.h>

    int global_flag = 1; //using 4 bytes

    void create_8_bytes()
    {
        /*
         * create 2 integers , total 8 bytes
        */
        int a = 3;
        int b = 6;

    }


    void create_4_bytes()
    {
        /*
         * 1 variable , total 4 bytes
        */
        int a  = 1;
    }

    void main()
    {
        create_8_bytes(); //8 bytes
        create_4_bytes(); //4 bytes
        puts("done");
    }

Сколько памяти потребуется для запускавышеуказанная программа?

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

В нетривиальных программах на C / C ++ обычно невозможно заранее узнать, сколько памяти вам понадобится во время выполнения.Это означает, что даже если ваш компилятор изо всех сил старается, он не всегда может создать программу, которая статически резервирует только необходимый объем памяти.

Современные платформы обычно различают на некотором уровне три типа памяти:

  1. память, которую ваша программа выделяет и использует на протяжении всей своей продолжительности (статические / глобальные переменные, функции и т. Д.)
  2. память, которую ваша программа может запросить во время выполнения, используя malloc и такие
  3. память стека

Объем статической памяти, в которой нуждается ваша программа, не может быть легко оценен, поскольку она сильно варьируется в зависимости от операционной системы, компилятора, стандартная библиотека и т. д. Однако ваша программа очень мала, поэтому было бы удивительно, если бы ей требовалось больше нескольких килобайт на любой платформе.На платформах, где память особенно ценна, вполне вероятно, что она может составлять всего несколько байтов.

Ваша программа не использует malloc или другие функции выделения, поэтому ей не требуется такая память.

Память стека - то, где волшебство происходит здесь.Стек - это область памяти, которую программа может использовать (и повторно использовать) при вызове функции.Его размер зависит от платформы (и обычно это где-то документируется), и операционные системы обычно оптимизируют ее использование таким образом, что память не становится доступной для программы до того, как она действительно попытается ее использовать.

Если выне хватает памяти стека, происходит неопределенное поведение.На платформах, где память драгоценна, вы можете испортить какую-то другую часть вашей программы.В наши дни на большинстве современных платформ вместо этого возникает сбой.

Если предположить, что ваша программа не была оптимизирована, а некоторые детали платформы скрыты, использование памяти будет выглядеть примерно так:

  • запуск программы
    • вы не используете стековую память
  • введите main: установить фрейм стека (~ 16 байт служебной работы)
    • вы используете 16 байт стековой памяти
  • введите create_8_bytes: установить фрейм стека (~ 16 байт служебной деятельности, 8 байт переменных)
    • выиспользовать 40 байт стековой памяти
  • оставить create_8_bytes: освободить кадр стека, который create_8_bytes использовал
    • вы используете 16 байтов памяти
  • enter create_4_bytes: установить фрейм стека (~ 16 байт служебных данных, 4 байта переменных)
    • используется 36 байт памяти
  • оставьте create_4_bytes: освободите кадр стека
    • вы используете 16 байт памяти
  • введите puts (используйте неизвестное количествопамять)
    • вы используете 16+ ???байт памяти
  • оставить puts
    • вы используете 16 байтов стековой памяти
  • оставить main
    • вы не используете стековую память

Как видите, объем используемой памяти увеличивается и уменьшается при входе и выходе из функций.

Хотя это обеспечивает правильную интуицию для использования стековой памяти, имейте в виду, что компиляторы, как правило, способны удалять части вашей программы, если они могут доказать, что это не изменит результат.Это означает, что вы можете ожидать, что ваши локальные переменные исчезнут, если вы их не используете, и даже если вы их используете, вполне возможно, что компилятор может использовать другие преобразования, которые позволят переменным вообще не использовать стековую память.Также возможно, что компилятор может использовать стековую память для вещей, которые вы явно не указали.

0 голосов
/ 05 февраля 2019

Зависит от компилятора, вашей среды, ОС и прочего.В любом случае это будет служебная информация, которая будет намного больше, чем пара байтов.

Кроме того, большая часть этой программы может быть оптимизирована, поэтому эти ints могут быть неактуальными.Программа может быть уменьшена до ничего кроме puts("done");.

Эти ints будут в стеке.Таким образом, create_8_bytes приведет к созданию нового фрейма стека, в котором будет место для двух целых чисел (и более, такого как указатель стека, поэтому снова числа будут отключены).Затем, когда create_8_bytes завершено, его кадр стека будет недействительным, а затем вызывается create_4_bytes, что делает кадр стека для хранения этого int.Все, конечно, предполагая, что ничего не встроено или не оптимизировано.

Вам, вероятно, хотелось бы знать, будут ли "1014 * и b из create_8_bytes и a из create_4_bytes" существовать "вв то же время.Они не будут.Конечно, фактическое потребление памяти не будет означать, что в связи с накладными расходами на вызовы функций сама программа (которая включает в себя загрузку необходимого кода за puts) и то, как ОС обрабатывает выделение памяти, в целом будут гораздо более значимыми, чемэти двенадцать байтов.И если вы компилируете отладочную сборку, то все это снова будет кардинально отличаться, так как компилятор не оптимизирует вещи, которые он в противном случае сделал бы, включает в себя то, что в противном случае не будет, а может дажесоздает изолированную среду для запуска вашей программы, которая занимает мегабайты даже для самого простого приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...