Переменные внутри функции

Модератор: Модераторы разделов

BratSinot
Сообщения: 812
ОС: Slackware64

Переменные внутри функции

Сообщение BratSinot »

Доброго времени суток!

Есть у меня, скажем, функция void tmp(), я объявил в ней переменные unsigned int q, w, e. В программе я вызвал эту функцию, она выполнилась и что станет с переменными? В стандарте есть такой пункт, что они должны уйти из памяти(ну или регистров процессора) или лучше самому проконтролировать посредством malloc(), free()?
Спасибо сказали:
Lan4
Сообщения: 339
Статус: hikki
ОС: Arch

Re: Переменные внутри функции

Сообщение Lan4 »

malloc() и free() работает же с указателями, вроде бы...

А переменные нормально сами "уйдут", если не указатели они.
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Переменные внутри функции

Сообщение BratSinot »

Lan4 писал(а):
18.05.2011 23:03
А переменные нормально сами "уйдут", если не указатели они.

В стандарте такое есть или это неписанное правило?
Спасибо сказали:
hippi90
Сообщения: 83
ОС: Debian testing

Re: Переменные внутри функции

Сообщение hippi90 »

Автоматические переменные создаются на стеке, при выходе из функции указатель стека перемещается и переменные уничтожаются.
Спасибо сказали:
Аватара пользователя
Portnov
Модератор
Сообщения: 1786
Статус: Матёрый линуксоид
ОС: Debian testing/unstable

Re: Переменные внутри функции

Сообщение Portnov »

Если только они не static.
Работа: Ubuntu 9.10
Дом: Debian testing/unstable и на всякий случай winxp в virtualbox.
Для разнообразия: моя домашняя страница -http://iportnov.ru
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Переменные внутри функции

Сообщение NickLion »

О-хо-хонюшки. Это ж основы, где Вы их пропустили?
Есть 3 вида памяти: статическая, стек, динамическая. Ну, также регистры, но то немного в стороне.
Все глобальные и статические переменные находятся в статической памяти - т.е. не повляются и не уничтожаются в течение времени жизни программы.
Все локальные переменные, а также параметры выделяются в стеке, при выходе из функции локальные переменные освобождаются путем увеличения головы стека. На практике это может быть не совсем так в связи с оптимизациями, но то другой разговор. Параметры освобождаются в соответствии с правилами вызова - вызываемой или вызывающей функцией.
Для работы с динамической памятью и только с ней используются функции malloc и free.
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Переменные внутри функции

Сообщение Crazy »

BratSinot писал(а):
18.05.2011 23:06
Lan4 писал(а):
18.05.2011 23:03
А переменные нормально сами "уйдут", если не указатели они.

В стандарте такое есть или это неписанное правило?

Это свойство конкретного языка программирования, а именно от области видимости.

Desipere in loco
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Переменные внутри функции

Сообщение BratSinot »

NickLion писал(а):
19.05.2011 08:41
О-хо-хонюшки. Это ж основы, где Вы их пропустили?

Теория!=Практика.

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

Это я знаю.

Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: Переменные внутри функции

Сообщение RasenHerz »

Ассемблер вам батенька надо изучить... И читать теорию, много читать.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5410
ОС: Gentoo

Re: Переменные внутри функции

Сообщение /dev/random »

BratSinot писал(а):
19.05.2011 13:34
Есть 3 вида памяти: статическая, стек, динамическая. Ну, также регистры, но то немного в стороне.
Все глобальные и статические переменные находятся в статической памяти - т.е. не повляются и не уничтожаются в течение времени жизни программы.
Все локальные переменные, а также параметры выделяются в стеке, при выходе из функции локальные переменные освобождаются путем увеличения головы стека. На практике это может быть не совсем так в связи с оптимизациями, но то другой разговор. Параметры освобождаются в соответствии с правилами вызова - вызываемой или вызывающей функцией.
Для работы с динамической памятью и только с ней используются функции malloc и free.

Это я знаю.

Если знаете, то к чему тогда эта тема?
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Переменные внутри функции

Сообщение Crazy »

/dev/random писал(а):
19.05.2011 13:47
Если знаете, то к чему тогда эта тема?

От незнания.

Desipere in loco
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Переменные внутри функции

Сообщение BratSinot »

/dev/random писал(а):
19.05.2011 13:47
BratSinot писал(а):
19.05.2011 13:34
Есть 3 вида памяти: статическая, стек, динамическая. Ну, также регистры, но то немного в стороне.
Все глобальные и статические переменные находятся в статической памяти - т.е. не повляются и не уничтожаются в течение времени жизни программы.
Все локальные переменные, а также параметры выделяются в стеке, при выходе из функции локальные переменные освобождаются путем увеличения головы стека. На практике это может быть не совсем так в связи с оптимизациями, но то другой разговор. Параметры освобождаются в соответствии с правилами вызова - вызываемой или вызывающей функцией.
Для работы с динамической памятью и только с ней используются функции malloc и free.

Это я знаю.

Если знаете, то к чему тогда эта тема?

Еще раз, теория!=практика. Единственный язык в котором можно на 99% быть уверенным что произойдет, это язык ассемблера.
Спасибо сказали:
watashiwa_daredeska
Бывший модератор
Сообщения: 4038
Статус: Искусственный интеллект (pre-alpha)
ОС: Debian GNU/Linux

Re: Переменные внутри функции

Сообщение watashiwa_daredeska »

BratSinot писал(а):
19.05.2011 18:32
Единственный язык в котором можно на 99% быть уверенным что произойдет, это язык ассемблера.
С таким уровнем уверенности я бы давно свихнулся :)
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5410
ОС: Gentoo

Re: Переменные внутри функции

Сообщение /dev/random »

BratSinot писал(а):
19.05.2011 18:32
Еще раз, теория!=практика. Единственный язык в котором можно на 99% быть уверенным что произойдет, это язык ассемблера.

Теория в таких вещах гораздо точнее практики. К примеру, некоторые умники привыкли, что на практике memcpy() всегда копирует от начала к концу, и тут ВНЕЗАПНО в некоторых версиях glibc она начала копировать от конца к началу. И их программы накрылись медным тазом. А ведь теория их предупреждала, что направление копирования memcpy() _не определено_.
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Переменные внутри функции

Сообщение BratSinot »

Это не тот момент.

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

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

_Bool main(void)
{
 if(<что-то>)
 {
  long double qwe;
  <что-то происходит>
 }

//Или такой вариант:
 {
  long double qwe;
  <что-то происходит>
 }

 return 0;
}
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Переменные внутри функции

Сообщение drBatty »

BratSinot писал(а):
19.05.2011 18:32
Еще раз, теория!=практика. Единственный язык в котором можно на 99% быть уверенным что произойдет, это язык ассемблера.

посмотрте скомпилированый код. там всё просто на самом деле.
BratSinot писал(а):
26.05.2011 18:17
if(<что-то>)
{
long double qwe;
<что-то происходит>
}

//Или такой вариант:
{
long double qwe;
<что-то происходит>
}

да. если в первом блоке qwe = 17, то во втором её значение не определено по стандарту, но на практике будет 17. Обычно. Но я-бы за такое вас уволил. И даже перестал-бы здороваться :(
Потому, что в самый важный момент, там нарисовалось-бы ВНЕЗАПНО 666. :(

BratSinot писал(а):
19.05.2011 18:32
Еще раз, теория!=практика.

что вас волнует? негативный вопрос? Может-ли злоумышленник узнать значения ваших данных из вашего стека? Ответ - да.
Позитивный вопрос? Можете-ли вы быть уверенны в сохранности использованного стека? Ответ - нет.
На практике всё будет отлично работать в тестах, и рухнет в продакшене.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Переменные внутри функции

Сообщение BratSinot »

да. если в первом блоке qwe = 17, то во втором её значение не определено по стандарту, но на практике будет 17. Обычно. Но я-бы за такое вас уволил. И даже перестал-бы здороваться :(
Потому, что в самый важный момент, там нарисовалось-бы ВНЕЗАПНО 666. :(

Кто мне там про теорию заливал? По стандарту, после первого блока переменная "уничтожается"(не знаю как это правильно назвать), а во втором блоке создается другая и вконце блока "уничтожается".
P.S. Вы точно про блоки правильно меня поняли?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Переменные внутри функции

Сообщение drBatty »

BratSinot писал(а):
26.05.2011 22:16
По стандарту, после первого блока переменная "уничтожается"(не знаю как это правильно назвать), а во втором блоке создается другая и вконце блока "уничтожается".

не было такого в стандарте. она выходит из области видимости. а когда входит - неопределённое значение. попробуйте.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: Переменные внутри функции

Сообщение BratSinot »

drBatty писал(а):
26.05.2011 23:02
BratSinot писал(а):
26.05.2011 22:16
По стандарту, после первого блока переменная "уничтожается"(не знаю как это правильно назвать), а во втором блоке создается другая и вконце блока "уничтожается".

не было такого в стандарте. она выходит из области видимости. а когда входит - неопределённое значение. попробуйте.

А то при обычном объявлении переменной без инициализации значение определенное? У меня в программе такие вещи временные, вроде перевалочных пунктов, например при замене переменных местами.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Переменные внутри функции

Сообщение eddy »

BratSinot писал(а):
26.05.2011 22:16
По стандарту, после первого блока переменная "уничтожается"(не знаю как это правильно назвать), а во втором блоке создается другая и вконце блока "уничтожается".

Никто ее не уничтожает. В "куче" при инициализации выделяется место, туда заносится значение. Когда вы выходите из области видимости переменной, занятая ею область "кучи" помечается как свободная. Но значение там продолжает храниться. Пока его не затрет другая переменная, если ей место там же будет выделено.
Вы же при удалении файла с диска не считаете, что занимаемые им блоки забиваются нулями/etc (конечно, если shred какой-нибудь не используете)?
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Переменные внутри функции

Сообщение NickLion »

eddy, поправка, если говорим о локальных переменных - то стек, а не куча.
Спасибо сказали:
Аватара пользователя
eddy
Сообщения: 3321
Статус: Красный глаз тролля
ОС: ArchLinux

Re: Переменные внутри функции

Сообщение eddy »

NickLion писал(а):
27.05.2011 00:48
если говорим о локальных переменных - то стек, а не куча.

Извиняюсь, вечно я их путаю...
RTFM
-------
KOI8-R - патриотичная кодировка Изображение
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU

Re: Переменные внутри функции

Сообщение sash-kan »

NickLion писал(а):
27.05.2011 00:48
стек, а не куча
нельзя сказать, что с точки зрения [не]очистки памяти они как-то принципиально отличаются.
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Переменные внутри функции

Сообщение NickLion »

sash-kan писал(а):
27.05.2011 02:13
NickLion писал(а):
27.05.2011 00:48
стек, а не куча
нельзя сказать, что с точки зрения [не]очистки памяти они как-то принципиально отличаются.

o_O
Отличаются как раз принципиально - стек работает по принципу стека (что не удивительно) - освобождаюся переменные в порядке обратном выделению. За счёт такого ограничения работает крайне быстро. В куче порядок освобождения произволен (что делает выделение/освобождение памяти более длительным процессом, возникает проблема фрагментации памяти и т.д.). Поэтому и куча - что всё свалено и порядка нет.
Ну и в силу своей простоты стек более тесно интегрирован в языки программирования - следить за удалением в стеке не надо. В куче такое невозможно - удаление можно опустить только в случае сборщика мусора или хотя бы умных указателей и т.п. обёрток.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Переменные внутри функции

Сообщение drBatty »

BratSinot писал(а):
27.05.2011 00:06
А то при обычном объявлении переменной без инициализации значение определенное?

нет
BratSinot писал(а):
27.05.2011 00:06
У меня в программе такие вещи временные, вроде перевалочных пунктов, например при замене переменных местами.

{int x,y;}
{int y,x;}

? убивать за такое надо.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Переменные внутри функции

Сообщение drBatty »

sash-kan писал(а):
27.05.2011 02:13
нельзя сказать, что с точки зрения [не]очистки памяти они как-то принципиально отличаются.

угу.
есть три отличия:
1) распределитель new может использовать св. память в своих целях.
2) отладочный new может забивать чем-то память.
3) и наконец, new можно перезагрузить.
NickLion писал(а):
12.06.2011 01:27
За счёт такого ограничения работает крайне быстро. В куче порядок освобождения произволен

та не. это не принципиально. часто распределитель new работает как стек.
куча возникает как раз в том случае, если new/delete не угадали стратегию распределения памяти.
NickLion писал(а):
12.06.2011 01:27
Ну и в силу своей простоты стек более тесно интегрирован в языки программирования - следить за удалением в стеке не надо. В куче такое невозможно

почему "невозможно"? возможно. и даже используется на практике (delete, который ничего не делает). задачи-то разные бывают... Кроме того, можно сделать например очередь - delete удаляет самый старый эл-т. А если delete пытается удалить не самый старый - ничего не происходит. Либо его выполнение откладывается - создаётся стек отложенных delete, и если удалился 17й эл-т, мы проверяем, не нужно-ли удалить за одно и 18й. Конечно, можно также сделать и стек.
NickLion писал(а):
12.06.2011 01:27
удаление можно опустить только в случае сборщика мусора или хотя бы умных указателей и т.п. обёрток.

сборщики мусора в С++ не очень хорошо работают. неоправданно сложная реализация. ИМХО.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
landgraf
Сообщения: 2142
Статус: *бунту ненавистник
ОС: linux

Re: Переменные внутри функции

Сообщение landgraf »

BratSinot писал(а):
19.05.2011 18:32
Еще раз, теория!=практика. Единственный язык в котором можно на 99% быть уверенным что произойдет, это язык ассемблера.

И Ada (по крайней мере в GNAT Pro.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Переменные внутри функции

Сообщение NickLion »

drBatty писал(а):
12.06.2011 02:29
NickLion писал(а):
12.06.2011 01:27
Ну и в силу своей простоты стек более тесно интегрирован в языки программирования - следить за удалением в стеке не надо. В куче такое невозможно

почему "невозможно"? возможно. и даже используется на практике (delete, который ничего не делает). задачи-то разные бывают... Кроме того, можно сделать например очередь - delete удаляет самый старый эл-т. А если delete пытается удалить не самый старый - ничего не происходит.

Нет, не то. Невозможно не вызывать delete, чтобы ЯП сам опознавал - нужен нам объект или нет. При работе со стеком явно определена область видимости и существования. В случае кучи, существование - хз когда нужно удалить. Без сборщика мусора этого не сделать. Всякие умные указатели - половинное решение, поскольку допускают утечки памяти при циклических ссылках.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Переменные внутри функции

Сообщение frp »

NickLion
Есть сборщики мусора и для C++. Один из них - http://sourceforge.net/projects/libgc/
ИМХО, это не совсем удобно, но оно есть и даже работает.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: Переменные внутри функции

Сообщение NickLion »

frp писал(а):
12.06.2011 16:02
NickLion
Есть сборщики мусора и для C++. Один из них - http://sourceforge.net/projects/libgc/
ИМХО, это не совсем удобно, но оно есть и даже работает.

Я не говорю, что их нет. Вопрос в том, что это не свойство языка C++. И даже если это особенность языка, то реализация представляет собой сложнейший процесс. Даже простейщий сборщик мусора - это необходимость хранения дерева связей ссылок и проход по нему. К тому же в том же C++ при передаче ссылки не на начало блока, а на середину всё становится намного хуже. Управляемые языки в этом плане ограничивают, но позволяют реализовать нормальный сборщик мусора (ценой снижения производительнорсти работы с указателями). В общем, рассуждать можно много, но суть в том, что стек и куча имеют общую глобалную цель, но задачи перед ними стоят разные.
Спасибо сказали: