Распределение памяти visual c++

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
FloyDos
Сообщения: 25
Зарегистрирован: 14 июн 2009, 16:08

Доброго времени суток! есть такая программа

Код: Выделить всё

int a,b,c,d;
int _tmain(int argc, _TCHAR* argv[])
{
  int e,f,g,h;
  cout << (long)&a <<endl;
  cout << (long)&b <<endl;
  cout << (long)&c <<endl;
  cout << (long)&d <<endl;
  cout << (long)&e <<endl;
  cout << (long)&f <<endl;
  cout << (long)&g <<endl;
  cout << (long)&h <<endl;
	return 0;
}
И вот результат:

4288876
4288872
4288868
4288864
1245024
1245012
1245000
1244988

То бишь, при глобальном объявлении переменных компиллятор почему-то выделяет память в обратном порядке :o
А в локальном вообще оставляет под каждую переменную по 12 байт, и тоже в обратном порядке.
Есть идеи, в чем причина?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

В локальном есть смысл. Так как данные выделяются на стеке, а текущий указатель стека при push'ах движется как раз от старшего к младшему адресу сегмента стека.
Для глобальных переменных - это компилятор депендед. Кто как хочет, так и делает.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
FloyDos
Сообщения: 25
Зарегистрирован: 14 июн 2009, 16:08

вот я идиот, точно же про стек забыл...
спасибо, Ромео. а вот почему 12 байт - все равно не понятно... если бы в глобальном - это как ты говоришь, компил. определяет.. но в локалке так почему?
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

FloyDos, а посмотреть под отладчиком на уровне ассемблера что происходит при входе в процедуру не пробовал? Наверняка можно понять, куда "теряются" лишние 8 байт стека.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

А сборка какая? Дебаг или Релиз? Часто компиляторы в дебаге вставляются баунд гварды, чтобы отслеживать переполнения. Плюс выравнивание проверь в настройках компилятора - скорее всего оно не 4 байта :)

А вообще, конечно, проще всего посмотреть в дизассемблере, как BBB предлагает.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
FloyDos
Сообщения: 25
Зарегистрирован: 14 июн 2009, 16:08

Romeo писал(а):А сборка какая? Дебаг или Релиз? Часто компиляторы в дебаге вставляются баунд гварды, чтобы отслеживать переполнения.
Оу, спасибо, так и есть, в релизе по 4 байта выделяется, а в дебаге по 12 :) Кроме того, в релизе порядок расположения локальных переменных прямой, как я и вычитал в книге...
Romeo писал(а): Плюс выравнивание проверь в настройках компилятора - скорее всего оно не 4 байта :)


А где это можно посмотреть?
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

FloyDos писал(а): А где это можно посмотреть?
Эта опция в каждой в среде расположен в своём месте. Просто облазь все настройки компилятора и найдёшь. Кстати, если в релизе стало 4 байта, то всё нормально. Выравнивание у тебя 4-х байтное.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Romeo писал(а):Эта опция в каждой в среде расположен в своём месте. Просто облазь все настройки компилятора и найдёшь. Кстати, если в релизе стало 4 байта, то всё нормально. Выравнивание у тебя 4-х байтное.
Кстати, возвращаясь к обнаруженному числу "12". 12-байтного выравнивания, насколько я понимаю, в настройках компилытора явно быть не может :) Так что, явно какая-то "служебная информация". В качестве версии "от балды" - что для контроля переполнения стека.
Hawk
Сообщения: 216
Зарегистрирован: 17 фев 2004, 14:52
Откуда: СПб
Контактная информация:

MSDN -
pack Specifies packing alignment for structure, union, and class members.
Т.е. на выравнивание разных переменных packing не влияет. Да и вообще расчитвать на какой-то порядок тут нельзя, стандартом такое не регламентируеся и компилятор волен делать как хочет.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

BBB, ты пропустил моё предыдущее сообщение - там всё написано уже :) В дебаге действительно вставляются баунд гварды, чтобы отслеживать переполнения переменных. Не стека, а именно переменных, так как переполнение стека отследить ещё проще - достаточно после push проверить флажок заёма, то есть иными слова проверить, что при уменьшении ESP его значение пересекло границу нуля.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ответить