| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Размещение переменных в стеке |
| Автор: FiMa1 10.5.2007, 16:07 | ||
Пытаюсь проанализировать размещение переменных в стеке... Почему разница между адресами переменных a и b равна 12 ?
Результат работы программы: size of int: 4 size of char: 1 p1 address: 0012FE7C value is 1 p2 address: 0012FF54 value is 2 a address: 0012FE6C not initialized b address: 0012FE60 value is 3 |
| Автор: Sartorius 10.5.2007, 16:14 |
| почитай disassembly и все увидишь... |
| Автор: Daevaorn 10.5.2007, 16:17 |
А почему бы и нет? Компилятор как хочет, так переменные и располагает. Добавлено через 7 минут и 49 секунд А вообще выключи ещё отладочную информацию |
| Автор: FiMa1 10.5.2007, 16:36 | ||
Видимо я неправильно понимаю организацию работы стека... Я предполагал, что объекты ложатся в стек последовательно. |
| Автор: FiMa1 10.5.2007, 17:30 |
| А можно чуть подробнее про это выравнивание? Первый раз слышу... Что-то связанное с отладочной информацией? |
| Автор: Daevaorn 10.5.2007, 17:41 |
http://en.wikipedia.org/wiki/Data_structure_alignment ну эти вещи не связаны. просто в твоем случае из-за режима отладки такие результаты |
| Автор: FiMa1 10.5.2007, 17:47 |
| Всем спасибо за участие! |
| Автор: FiMa1 11.5.2007, 17:24 | ||
Выключил отладочную информацию - выставил Release в VS 2005.
Результат работы программы: 4 0012FEE4-0012FEE0=1 Почему 0012FEE4-0012FEE0=1, а не 4. Если все-таки 4, то почему 4 байта, ведь имеем две целых переменных по 4 байта каждая, т.е. 8 байт. |
| Автор: nickless 11.5.2007, 17:35 | ||||
Для типизированных указателей разница (да и всё остальное тоже) вычисляется в размерах типов, т.е. в этом случае в intах.
Если сделать
то выдаст 4, потому что в указателе адрес _начала_ переменной |
| Автор: FiMa1 14.5.2007, 14:54 | ||||
Имеем нижеприведенный код.
Результат работы программы: 0012FEE4 0012FEE0 STACK 1::p1 0012FED4 value is 1 STACK 1::p2 0012FEE0 value is 2 STACK 1::i 0012FEC0 value is 1 STACK 1::i1 0012FEB8 value is 3 STACK 1.1::i 0012FEB4 value is 2 STACK 1.1::i2 0012FEC4 value is 5 STACK 1.1.1::i 0012FEC8 value is 9 STACK 1.1.1::i3 0012FEBC value is 7 STACK 1.1::i 0012FEB4 value is 8 STACK 1.1.1::d 0012FEC8 value is 16 STACK 1.1::i 0012FEB4 value is 3 STACK 1.1::s 0012FEBC value is abs Почему 0012FEC0 (STACK 1::i) - 0012FEB8 (STACK 1::i1) = 8 (отладочная информация выключена - Release ) ? Да и вообще, по-моему, на моей машине стек должен "расти" вниз... |
| Автор: JackYF 14.5.2007, 16:13 |
Скорее всего, имеем, опять-таки, выравнивание. |
| Автор: FiMa1 14.5.2007, 16:20 | ||
От этого можно хоть как-нибудь избавиться? Хочу просмотреть чисто работу стека... IDE VS 2005. |
| Автор: Daevaorn 14.5.2007, 16:50 |
А чем эта не чиста? Теорию можно прочитать в умных книжках, а тут практика - тоже полезно. |
| Автор: FiMa1 15.5.2007, 11:38 | ||
|
| Автор: v_nikolaev 15.5.2007, 13:03 |
| Чего гадать? Не лучше ли выложить дизассемблер этой функции сюда, а потом и говорить? Заодно сказать, что за компилятор. Может, там вообще в стек ничего не записывается, а печатаются значения начала стека процедуры со статически известным сдвигом |
| Автор: FiMa1 15.5.2007, 13:47 | ||
Про компилятор говорилось - VS 2005. Дизасм прилагается... |
| Автор: adLucem 15.5.2007, 14:05 | ||
Удалите из вывода ссылки на строковые переменные (потому что они помещаются в стек для передачи в функции) и наслаждайтесь.
Вывод 0012FF70 0012FF6C 0012FF60 0012FF6C 0012FF48 0012FF44 0012FF40 0012FF4C 0012FF50 0012FF54 0012FF40 0012FF54 0012FF40 0012FF54 |
| Автор: FiMa1 15.5.2007, 16:05 |
| Спасибо! |
| Автор: FiMa1 15.5.2007, 16:52 | ||
Ммм.. не понял чем наслаждаться... Скомпилировал один в один, у меня вот какой результат: 0012FEE4 0012FEE0 0012FED4 0012FEE0 0012FEBC 0012FEB8 0012FEB4 0012FEC0 0012FEC4 0012FEC8 0012FEB4 0012FEC8 0012FEB4 0012FEC8 Т.о. 0012FEBC - i, 0012FEB8 - i1. Стек "растет вверх"... Дальше 0012FEB4 - i, 0012FEC0 - i2, стек растет "вниз". Да и у вас, я смотрю тоже i и i1 разместились с 0012FF48 и 0012FF44, соответственно...? Что такое #pragma push ( 1 ), прокомментируйте тоже, пожалуйста. |
| Автор: JackYF 15.5.2007, 17:15 | ||||||
Выравнивание. Как часть явной или неявной оптимизации компилятора. Или лучше пускай переменные будут вплотную друг к дружке, но код твой выполняться медленнее?
16.
Скорее всего, опять выравнивание. P.S. Ну какая тебе нафиг разница, в каком порядке у тебя переменные в стеке лежат? Как программисту на С/С++? Пиши тогда на Ассемблере, сам всем будешь управлять |
| Автор: FiMa1 15.5.2007, 17:33 |
| Ну на том и порешили. Всем большое спасибо! Топик закрыт, ушел учить ассемблер...... |
| Автор: v_nikolaev 24.5.2007, 10:19 | ||
насколько я помню, это работа с выравниванием, только чтобы вырубить его, кажется, нужно писать #pragma push ( 0 ) - или я что-то путаю... 2 JackYF: программисту C/C++ и вправду не к чему это знать, а иногда даже вредно это знать однако бывают случаи, когда умение правильно выравнивать важно - например, при связки C - ASM. |
| Автор: Fazil6 24.5.2007, 10:34 | ||||
вообще-то я так не видел никогда. Обычно
так еще можно
|
| Автор: JackYF 24.5.2007, 13:06 | ||
согласен, пожалуй. Но тогда будет такой геморрой на свою голову... |
| Автор: dumb 24.5.2007, 14:23 | ||
выравнивание "всплывает" при любой передаче структуры "наружу" - по сети, в файл, итд. так что знать такие вещи необходимо, чтобы не было |
| Автор: JackYF 24.5.2007, 16:57 |
Выравнивание элементов внутри структуры и выравнивание переменных в стеке - это разные вещи. Безусловно, про выравнивания структур знать надо. А вот особенности компилятора здесь идут нафиг. |
| Автор: dumb 24.5.2007, 18:22 | ||
а. это я выпал из темы... вы ж про стек... в таком случае вообще непонятно, причем тут выравнивание. понятно, что можно выравнивать элементы в стеке на какие-то границы, но на практике выравнивание всегда идет на 4(не трогаем 16ти и 64ех битные режимы). и, afaik, возможности управлять выравниванием в стеке просто нету. прагму какую-то по ходу дела изобрели... почему автор топика решил, что переменные в стеке должны располагаться в порядке их объявления в исходнике - зОгадкО. а с тем, что программеру C/C++ в общем случае не нужно знать, как именно располагаются данные(где бы то ни было), целиком и полностью согласен. |
| Автор: v_nikolaev 25.5.2007, 08:50 |
| Да, но разговор тут уже зашёл не только о стеке, и pragma, кажется, к стеку отношения не имела, хотя я сам уже плохо помню, что ето за прагма Выравнивание в стеке нуэно при связке асм-с, выравнивание в структуре и подавно нужно Но затачиваться под работу стека с локальными переменными нельзя - это приводит к кривым последствиям, потому лучше этой темой не заморачиваться я тоже когда-то обижался на оптимизатор, за то что он инварианты из цикла выносит и тп, а вот ты добавь обращение к адресу через указатель, глядишь, он и не вынесет инвариантов удивляться, что прога делает только то, что от неё просят не стоит. |