2016-11-10 3 views
2
#include<stdio.h> 
int main() 
{ 
    int a,b; 
    float e; 
    char f; 
    printf("int &a = %u\n",&a); 
    printf("int &b = %u\n",&b); 
    printf("float &e = %u\n",&e); 
    printf("char &f = %u\n",&f); 
} 

Выход являетсяли память выделяется, когда переменная не используется в с

int &a = 2293324 
int &b = 2293320 
float &e = 2293316 
char &f = 2293315 

Но когда я использую этот код и заменить Printf для float--

#include<stdio.h> 
int main() 
{ 
    int a,b; 
    float e; 
    char f; 
    printf("int &a = %u\n",&a); 
    printf("int &b = %u\n",&b); 
    printf("char &f = %u\n",&f); 
} 

Затем выходной сигнал

int &a = 2293324 
int &b = 2293320 
char &f = 2293319 

Адрес здесь не указан для плавания, но он указан сверху. Мои вопросы:

  1. Является ли память не выделена для переменных, не используемых в программе?
  2. Почему адреса распределяются в порядке убывания. ex-it идет от 2293324 до 2293320?
+7

Сделайте себе одолжение и используйте '% p' при печати адресов. – WhozCraig

+5

1) Зависит от оптимизаций, выполняемых компилятором 2) Зависит от компилятора. – mascoj

+0

Где находится C++? – KABoissonneault

ответ

4

1) Является ли память не распределенной для переменных, не используемых в программе?

Да, что может случиться, компилятору разрешено его оптимизировать.

2) Почему адреса распределяются в порядке убывания. ex-it идет от 2293324 до 2293320?

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

+0

Чтобы уточнить: для этого нет никакой гарантии, и в стандарте 4 C нет стека. Действительно, существуют реализации, которые вообще не используют стек для переменных. Или полностью возрастающий стек. – Olaf

+0

@ Олаф Пытался улучшить формулировку. Я думаю, что то же самое относится и к стандарту c и C++ в этом случае. –

+0

Я просто не был после редактирования. Просто хотел отбросить nitpicky комментарий ;-) – Olaf

2

1) Является ли память не распределенной для переменных, не используемых в программе?

Это разрешенная оптимизация; если неиспользуемая переменная не влияет на наблюдаемое поведение программы, компилятор может просто полностью отказаться от нее. Обратите внимание, что большинство современных компиляторов будут предупреждать вас о неиспользуемых переменных (чтобы вы могли либо удалить их из кода, либо сделать что-то с ними).

2) Почему адреса распределяются в порядке убывания. ex-it идет от 2293324 до 2293320?

Компилятор не обязан выделять хранилище для отдельных объектов в любом конкретном порядке, поэтому не предполагайте, что ваши переменные будут распределены в том порядке, в котором они были объявлены. Кроме того, помните, что на x86 и некоторых других системах стек растет «вниз» к уменьшающимся адресам. Помните, что вершина любого стека - это просто место, где что-то совсем недавно было нажато - это не имеет никакого отношения к относительным значениям адреса.

0

Хотя стандарт не требуется, локальные переменные универсально расположены в стеке программ.

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

SUBL #SOMETHING, SP 

Где НЕЧТО является количество требуемого пространства и SP является регистр указателя стека .. В первом примере, НЕЧТО, вероятно, 13. Тогда адрес:

f is 0(SP) 
    e is 1(sp) 
    b is 5(sp) 
    a is 9(sp) 

Я предполагаю, что ваш компилятор не выровнял указатель стека. Часто они давая что-то подобное:

f is 3(SP) 
    e is 4(sp) 
    b is 8(sp) 
    a is 12(sp) 

И НЕЧТО будут округлены до 16 на 32-битной системе.

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

Память не выделена для переменных, не используемых в программе?

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

Компилятору не нужно резервировать место для переменных, которые не используются. Их можно оптимизировать. Как правило, существуют параметры компилятора, чтобы указать, не делать это для отладки.

Почему адреса распределены в порядке убывания. ex-it идет от 2293324 до 2293320?

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

Куча будет расти в направлении более высоких адресов. Стек будет расти в сторону кучи (более низкие адреса).

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

Нет особого требования, чтобы компилятор отображал переменные в стек в порядке убывания, но есть вероятность 50/50, что так оно и будет.