PDA

Просмотр полной версии : [Вопрос] Глобальная переменная, которая постоянно перезаписывается



SteveStage
22.11.2019, 17:51
Видел в коде использование глобального массива totalstring, и понял принцип - под него выделяется место в стеке (только под него), и он перезаписывается, вместо создания локальных массивов, занимающие дополнительное место в стеке (причем они даже не обнуляются)

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

kennytowN
22.11.2019, 20:01
Обычно, если ты хочешь использовать глобальный массив - ты должен постоянно создавать новый, если будешь использовать его совершенно в другой системе, иначе, как ты и сказал, будут ошибки.

execution
22.11.2019, 20:45
Код выполняется синхронно, тоесть не начнётся одно дейсвтие, пока не закончится предыдущее.

Поправьте, если не прав.
Когда ты создаёшь глобальную переменную, то под неё выделяется место в физической памяти. Когда создаёшь локальную - стэковая память.
Многие используют глобальный массив, чтобы не забивать стэковую память, что лучше всего не делать.

DeimoS
23.11.2019, 08:36
Во-первых, ты сам себе противоречишь, ибо если ты создаёшь глобальный массив, то ты не потребляешь стек.
Во-вторых, создавать глобальные массивы ради "экономии стека" не стоит, ибо стек экономить не нужно. Подробнее тут (http://pro-pawn.ru/showthread.php?15835-%D0%93%D0%BB%D0%BE%D0%B1%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9-%D0%9B%D0%BE%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9&p=88852&viewfull=1#post88852) (читать от указанного поста и далее).

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



Код выполняется асинхронно, тоесть не начнётся одно дейсвтие, пока не закончится предыдущее.

Поправьте, если не прав.
Когда ты создаёшь глобальную переменную, то под неё выделяется место в физической памяти. Когда создаёшь локальную - стэковая память.
Многие используют глобальный массив, чтобы не забивать стэковую память, что лучше всего не делать.

Сформулировал правильно, но перепутал "асинхронно" с "синхронно")

SteveStage
23.11.2019, 17:00
Как я понял, память и стек работают вот так (с массивами тоже самое): https://ibb.co/gJfVcdg

И стек постоянно очищается (становится доступным) для нового участка кода

DeimoS
23.11.2019, 17:49
Стек отчищается не постоянно, а в момент, когда закончился обрабатываться определённый блок кода. В теме, на которую давал ссылку, есть же пример. И, в целом, принцип работы стека/кучи в Pawn довольно схож с другими ЯП. Разве что вариантов взаимодействия с ними меньше и часть логики прописана изначально.

Ну и если вдаваться в подробности, то правильнее будет так:

https://i.imgur.com/9M55mWq.png

SteveStage
23.11.2019, 18:33
Ну и если вдаваться в подробности, то правильнее будет так:

https://i.imgur.com/9M55mWq.png


Верно, но мы сейчас говорим про переменные/массивы, а куча не связана с ними (не хранит их), вроде как хранит вычисления (вычитал из инета:) http://pawn-wiki.ru/index.php?/topic/42005-stak-segment-dannii-kucha/ и начинается с конца


Стек отчищается не постоянно, а в момент, когда закончился обрабатываться определённый блок кода. В теме, на которую давал ссылку, есть же пример. И, в целом, принцип работы стека/кучи в Pawn довольно схож с другими ЯП. Разве что вариантов взаимодействия с ними меньше и часть логики прописана изначально.

Я же это и имел ввиду, но блоки кода выполняются не 30 минут, а пару секунд => во время работы сервера стек постоянно очищается от предыдущего блока кода и переходит к следующему блоку кода.

И еще, хотел бы узнать, как можно увеличить стек (вдруг пригодится)? Лучше быть готовым и не пригодится, чем не быть готовым и пригодится

DeimoS
23.11.2019, 18:41
Так я же и говорю: если вдаваться в подробности.
Изменять количество памяти, которая будет выделена под стек/кучу, можно так
#pragma dynamic количество_ячеек

DeimoS
24.11.2019, 02:36
Для стека и кучи выделяется одинаковое количество памяти? Окей

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

UPD: я, похоже, вместо объединения сообщений случайно их удалил =\ Извиняюсь. Не стоило модерировать в 5 часов ночи)...

SteveStage
24.11.2019, 16:08
Стек и куча - это один сегмент данных. То бишь, те 16384 байта, которые выделяются по стандарту - это и стек, и куча. Просто данные стека записываются с начала, а данные кучи - с конца.

Окей, т.е. если стек заполнен на 8 кб, и куча на 8 кб - будет переполнение?


UPD: я, похоже, вместо объединения сообщений случайно их удалил =\ Извиняюсь. Не стоило модерировать в 5 часов ночи)...

Я отправил:

1) 1 ячейка = 4 байта. Стандартный размер стека 4096 ячеек, или 16384 байта

2) То, что ты процитировал

DeimoS
24.11.2019, 16:32
Окей, т.е. если стек заполнен на 8 мб, и куча на 8 мб - будет переполнение?

Эмм, ну если вопрос ставить так то да, будет. А вообще куча никак до таких размеров не разрастётся в нормальных условиях.