PDA

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



naxxyelite
01.01.2018, 22:06
Доброго времени суток, для меня возник еще вопрос, что же все таки в конечном итоге лучше и рациональнее использовать,
везде где читаю, вижу разные мнения, или ответы, при которых возникают еще вопросы, кто то пишет, что рациональнее юзать локальные, кто то пишет что глобальные, мол он не жрёт стэк и так далее, кто то пишет вообще, что в определенных ситуациях глобальные, а где то локальные, зависит мол якобы от случая, так вот оттуда возникает вопрос, в каких это именно определенных ситуациях рациональнее использовать глобальный, а в каких локальный, кто то так же пишет, что если постоянно использовать глобальный, то могут возникнуть проблемы, оттуда вопрос, что же это за проблемы, далее еще вопрос по поводу чистки массива, пишут везде что опять же при определенных ситуациях необходимо чистить массив, т.е есть несколько случаев, когда необходимо его чистить? Слышал только тот вариант, что чистить необходимо только при использовании strcat, а при format - функция сама якобы его чистит, в общем прошу знающих в этом толк дать окончательный ответ и поставить на этом точку.


С новым годом!

DeimoS
01.01.2018, 23:00
пишет что глобальные, мол он не жрёт стэк

А там пишут какой в этом плюс?
Стэк и является подобием глобального массива. И когда ты создаёшь локальный массив, ты просто используешь часть этого "глобального массива", а не выделяешь дополнительную память.
А когда создаёшь глобальный, ты выделяешь дополнительную память (стэк при этом не перестанет существовать и так же будет занимать место).

Ко всему прочему, используя глобальный массив, ты создаёшь больше возможностей допустить ошибку в коде. Например, представим, что мы создали глобальный массив "global_string". Его мы используем в некоторых ситуациях, когда нужно записать текст. Но тут нам нужно написать какую-то систему, в которой, например, выводится текст в чат, а перед этим форматируется в другом массиве, который нужен для работы системы (то бишь, там используется свой массив (назовём его "local_string"), а не global_string). Дабы упростить себе жизнь, мы копируем похожий код с форматированием из другой системы, в которой используется наш global_string

format(global_string, sizeof(global_string), "...", ...);
SendClientMessage(playerid, -1, global_string);
И далее решим просто заменить текст в форматировании и массив на нужный нам

format(local_string, sizeof(local_string), "текст", ...);
SendClientMessage(playerid, -1, global_string);
Но отвлекаемся и забываем изменить имя массива в SendClientMessage, оставляя там global_string, а не устанавливая local_string.
Компилируя, мы не получим никаких ошибок, ибо для компилятора в этом коде всё нормально (и local_string существует, и global_string). Но когда начнём тестировать, на выходе получим совсем не те сообщения, которые должны быть. И не факт, что эта опечатка обнаружится сразу => на исправление уйдёт своё время.

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

new string[...];
format(string, sizeof(string), "...", ...);
SendClientMessage(playerid, -1, string);
То уже во втором случае компилятор бы сообщил об ошибке, так как в той системе используется совершенно другой массив.

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

naxxyelite
02.01.2018, 00:54
Хорошо, спасибо за ответ, я просто занимаюсь разработкой мода с 0, и с самого начала использовал локальные с точным подсчётом ячеек, но после того как прочитал начитался мнений про то, что используйте ка лучше глобальные, поешл быстренько не думая заменил локальные на глобальный.

Теперь вопрос еще касаемо стэка, до вашего ответа я думал что при создании локального, выделяется память из стека и выделяется она и никуда не возвращается, т.е думал, что работает это как эффект грыжи, которая постепенно нарастает и что памяти стека на финальном этапе написания мода мне не хватит, я ошибался? :)

"Но отвлекаемся и забываем изменить имя массива в SendClientMessage" ну тут проблема рода аля проглазел, а какие то более серьезные проблемы могут возникнуть, путанницы какие то, рандомные проблемы, которые вылезают на большой онлайне итд?

DeimoS
02.01.2018, 01:11
Теперь вопрос еще касаемо стэка, до вашего ответа я думал что при создании локального, выделяется память из стека и выделяется она и никуда не возвращается, т.е думал, что работает это как эффект грыжи, которая постепенно нарастает и что памяти стека на финальном этапе написания мода мне не хватит, я ошибался? :)

Ошибался.
Как я уже сказал, стэк можно описать как обычный глобальный массив, только с уже заложенной логикой работы и некоторыми другими хитростями. Вся память, что резервируется в блоке кода (от { до }), отчищается после того, как коллбэк, в котором объявлены переменные, вернёт какое-либо значение (return). И уже последующие переменные опять будут занимать это место.
Это крайне упрощённое объяснение и не очень точное. При желании, можешь сам нагуглить информацию о стеке и куче.


"Но отвлекаемся и забываем изменить имя массива в SendClientMessage" ну тут проблема рода аля проглазел, а какие то более серьезные проблемы могут возникнуть, путанницы какие то, рандомные проблемы, которые вылезают на большой онлайне итд?

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

naxxyelite
02.01.2018, 01:45
Все, спасибо большое.

Jolygolf
02.01.2018, 01:47
Ошибался.
Как я уже сказал, стэк можно описать как обычный глобальный массив, только с уже заложенной логикой работы и некоторыми другими хитростями. Вся память, что резервируется в блоке кода (от { до }), отчищается после того, как коллбэк, в котором объявлены переменные, вернёт какое-либо значение (return). И уже последующие переменные опять будут занимать это место.
Это крайне упрощённое объяснение и не очень точное. При желании, можешь сам нагуглить информацию о стеке и куче.



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

Правильно ли я понимаю, на каждый блок кода ({ }), как Вы выразились, выделяется указанный размер 16384 bytes (16384/4 = 4048 ячеек) в компиляторе? Если да, то какой смысл в его подсчете компилятором?

DeimoS
02.01.2018, 02:15
Правильно ли я понимаю, на каждый блок кода ({ }), как Вы выразились, выделяется указанный размер 16384 bytes (16384/4 = 4048 ячеек) в компиляторе? Если да, то какой смысл в его подсчете компилятором?

Эмм, нет. Ничего не выделяется на каждый блок. Есть просто стэк, под который изначально выделяется заданное количество памяти, а уже после эта память используется коллбэками.
Не для каждого коллбэка в отдельности свой стэк, а один общий (ибо Pawn однопоточен и всё такое).
Но подсчёт происходит для каждого коллбэка/функции в отдельности, ибо данные в стэке начинают записываться при начале обработки того или иного коллбэка/функции и удаляются из стэка только когда происходит возврат какого-либо значения (return). И то значение, которое компилятор выдаёт после компиляции, в статистике, не является суммой всех локальных переменных/массивов и прочего в моде, а вычисляется исходя из конкретной функции вашего скрипта, которая потребляет больше всего памяти.

Ну, то есть, как я сказал ранее, для каждой функции компилятор рассчитывает стэк в отдельности, ибо когда функция возвращает значение, вся информация удаляется из стэка и, соответственно, места для новой информации вновь становится столько же, сколько было изначально. Из этого получается, что если, например, OnPlayerConnect потребляет 90% стэка (больше всего в скрипте), а OnDialogResponse всего 50%, достаточно указать значение OnPlayerConnect, которое является самым большим и которого, соответственно, хватит для остальных функций.

- - - Добавлено - - -

Вообще каждый сам может наглядно поэкспериментировать со стэком, включив режим отладки (-d3) и создавая разные массивы.

Например, мои слова о том, что локальные переменные/массивы существуют только в том блоке, в котором они объявлены, проверяются следующим образом:
Сначала сделаем 3 массива в одном блоке кода

public OnGameModeInit()
{
new string1[1000];
string1[0] = 0;
string1[1] = string1[0];

new string2[1000];
string2[0] = 0;
string2[1] = string2[0];

new string3[1000];
string3[0] = 0;
string3[1] = string3[0];
return 1;
}
И получим следующую статистику:

Stack/heap size: 16384 bytes; estimated max. usage=3064 cells (12256 bytes)

А после вынесем каждый массив в свой блок кода

public OnGameModeInit()
{
{
new string1[1000];
string1[0] = 0;
string1[1] = string1[0];
}
{
new string2[1000];
string2[0] = 0;
string2[1] = string2[0];
}
{
new string3[1000];
string3[0] = 0;
string3[1] = string3[0];
}
return 1;
}
И уже результат будет таков:

Stack/heap size: 16384 bytes; estimated max. usage=1064 cells (4256 bytes)


public OnGameModeInit()
{
{// Первый блок кода открылся
new string1[1000];// В стеке зарезервировалось 1000 ячеек под метку "string1"
string1[0] = 0;
string1[1] = string1[0];
}// Блок закончился и зарезервированные ячейки перестали быть зарезервированными
{
new string2[1000];// Этот массив занял не новые 1000 ячеек, а те, что занимал прошлый массив
string2[0] = 0;
string2[1] = string2[0];
}// И опять всё отчистилось
{
new string3[1000];// И опять прошлые 1000 ячеек
string3[0] = 0;
string3[1] = string3[0];
}// В итоге этот код занял не 3к ячеек, а всего 1к
return 1;
}

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


P.S. Я всё же постараюсь в ближайшее время выделить время на написание статьи о памяти, которую планировал уже очень дано, и там уже постараюсь описать всё это подробнее.

Jolygolf
02.01.2018, 02:43
Эмм, нет. Ничего не выделяется на каждый блок. Есть просто стэк, под который изначально выделяется заданное количество памяти, а уже после эта память используется коллбэками.
Не для каждого коллбэка в отдельности свой стэк, а один общий (ибо Pawn однопоточен и всё такое).
Но подсчёт происходит для каждого коллбэка/функции в отдельности, ибо данные в стэке начинают записываться при начале обработки того или иного коллбэка/функции и удаляются из стэка только когда происходит возврат какого-либо значения (return). И то значение, которое компилятор выдаёт после компиляции, в статистике, не является суммой всех локальных переменных/массивов и прочего в моде, а вычисляется исходя из конкретной функции вашего скрипта, которая потребляет больше всего памяти.

Ну, то есть, как я сказал ранее, для каждой функции компилятор рассчитывает стэк в отдельности, ибо когда функция возвращает значение, вся информация удаляется из стэка и, соответственно, места для новой информации вновь становится столько же, сколько было изначально. Из этого получается, что если, например, OnPlayerConnect потребляет 90% стэка (больше всего в скрипте), а OnDialogResponse всего 50%, достаточно указать значение OnPlayerConnect, которое является самым большим и которого, соответственно, хватит для остальных функций.

- - - Добавлено - - -

Вообще каждый сам может наглядно поэкспериментировать со стэком, включив режим отладки (-d3) и создавая разные массивы.

Например, мои слова о том, что локальные переменные/массивы существуют только в том блоке, в котором они объявлены, проверяются следующим образом:
Сначала сделаем 3 массива в одном блоке кода

public OnGameModeInit()
{
new string1[1000];
string1[0] = 0;
string1[1] = string1[0];

new string2[1000];
string2[0] = 0;
string2[1] = string2[0];

new string3[1000];
string3[0] = 0;
string3[1] = string3[0];
return 1;
}
И получим следующую статистику:


А после вынесем каждый массив в свой блок кода

public OnGameModeInit()
{
{
new string1[1000];
string1[0] = 0;
string1[1] = string1[0];
}
{
new string2[1000];
string2[0] = 0;
string2[1] = string2[0];
}
{
new string3[1000];
string3[0] = 0;
string3[1] = string3[0];
}
return 1;
}
И уже результат будет таков:



public OnGameModeInit()
{
{// Первый блок кода открылся
new string1[1000];// В стеке зарезервировалось 1000 ячеек под метку "string1"
string1[0] = 0;
string1[1] = string1[0];
}// Блок закончился и зарезервированные ячейки перестали быть зарезервированными
{
new string2[1000];// Этот массив занял не новые 1000 ячеек, а те, что занимал прошлый массив
string2[0] = 0;
string2[1] = string2[0];
}// И опять всё отчистилось
{
new string3[1000];// И опять прошлые 1000 ячеек
string3[0] = 0;
string3[1] = string3[0];
}// В итоге этот код занял не 3к ячеек, а всего 1к
return 1;
}

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


P.S. Я всё же постараюсь в ближайшее время выделить время на написание статьи о памяти, которую планировал уже очень дано, и там уже постараюсь описать всё это подробнее.

Спасибо! Теперь стало все предельно понятно и просто.

123
02.01.2018, 05:32
И в конечном итоге, когда мод вырастет во что-то стоящие, он захлебнется от огромного разнообразия повторяющихся, бессмысленных локальных массивов, которые перегрузят абсолютно все паблики, постоянно будут вынуждать увеличивать место под стэк, и будут только портить читаемость кода и удобства его написания.

Самый главным плюсом использование локальных массивов, тут называют удобства кода, исключение каких-то ошибок, а если разобраться подробнее, если один человек занимается модом, о каком удобстве идет речь? Считать каждый раз ячейки, что бы стэк ушел не запредельно далеко? Использовать отдельных стринг для каждого формата, который в одном участке кода повторяется овер999 раз? Дабы не допустить "ошибку". Серьёзно?

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

DeimoS
02.01.2018, 11:03
И в конечном итоге, когда мод вырастет во что-то стоящие, он захлебнется от огромного разнообразия повторяющихся, бессмысленных локальных массивов, которые перегрузят абсолютно все паблики, постоянно будут вынуждать увеличивать место под стэк, и будут только портить читаемость кода и удобства его написания.

А теперь прочти тему до конца, если не понимаешь как работают эти самые массивы, и пойми, что если ты не создашь однажды массив в 4к ячеек, ничто не "захлебнётся". Хотя, если судить по написанному тобой, складывается впечатление, что ты не очень сильно паришься по поводу того, как написан твой код и какова его структура. С таким подходом да, у тебя там всё рано или поздно захлебнётся.
Да и повторю ещё раз: стэк - тот же глобальный массив. От того, что ты увеличишь его, ничего не изменится и хуже не станет. Уж лучше прибавить немного к стэку и использовать прошлые 4к ячеек, что были в нём, чем создавать ещё один массив, выделяя дополнительные 4к ячеек.


Самый главным плюсом использование локальных массивов, тут называют удобства кода, исключение каких-то ошибок, а если разобраться подробнее, если один человек занимается модом, о каком удобстве идет речь? Считать каждый раз ячейки, что бы стэк ушел не запредельно далеко? Использовать отдельных стринг для каждого формата, который в одном участке кода повторяется овер999 раз? Дабы не допустить "ошибку". Серьёзно?

Серьёзно. Ты тут не на сервер поиграть зашёл, а пишешь скрипты. И "тяп-ляп" делать не получится. Очень многое в программировании придумано для того, чтоб тебя обезопасить от лишних ошибок. Тот же Pawn, на котором ты пишешь, для того и был придуман.
И никто не называет это главным плюсом. Используя локальные массивы, ты, как минимум:
1) Не тратишь лишнюю память в сегменте данных (а стэк, я напомню, является лишь частью этого сегмента данных и выделенная под стэк память никуда не исчезнет, если вы не будете его использовать)
2) Делаешь код логичнее и читабельнее (по инициализации видно, что дальше в коде используется массив на такое-то количество ячеек)
3) Как я уже писал ранее, избавляешься от возможности допустить ошибку (мной описанный случай - не единственный. Так же можно не обнулить массив, например, где-нибудь в цикле, в котором идёт форматирование и на выходе получить кашу из текста при многократном использовании кода). В перспективе это сэкономит в разы больше времени, нежели если ты будешь тратить на подсчёт и объявление этого массива



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

Выше сказано лишь то, что кто-то не разбирается в поставленном вопросе и делает из этого какие-то выводы (особенно забавно читать про "захлёбывание" было). Про все "крупные геймплеи" говорить бессмысленно, ибо достаточно взглянуть на остальной код, чтоб понять как они написаны (и речь не о том, что авторы плохие и написали всё плохо, а о том, что эти скрипты начинали писаться очень давно и тогда о подобном особо не думали (чтоб это понять, достаточно лишь на официальный форум зайти и почитать темы ~2010 года. Там и stock быстрее pubic, и массивы лучше объявлять в 512 ячеек. а не 1024, ибо это оптимизированнее, и много всего ещё весёлого, от чего потом долгое время избавлялись на этом форуме). Не всегда "крупное" означает "хорошо написанное". Смотреть нужно не на написанные моды, а на теорию, в которой объясняется принцип работы. И уже исходя из этого делать выводы). А тебя я хочу поздравить с тем, что ты потратил в 3 раза больше памяти (ну или сколько у тебя массивов) и получил из этого ровным счётом ни-че-го хорошего. Ну кроме упоения своей лени.

- - - Добавлено - - -

И давайте не будем сейчас путать "как правильно" с "как мне удобно". Люди спросили именно о первом и ни к чему сейчас полемику устраивать.
А то, что гораздо легче пойти и ограбить какую-нибудь старушку, чем самому заработать - это да, не поспоришь. Но, опять же, правильно ли это? Не думаю.

123
02.01.2018, 12:35
И давайте не будем сейчас путать "как правильно" с "как мне удобно". Люди спросили именно о первом и ни к чему сейчас полемику устраивать.
А то, что гораздо легче пойти и ограбить какую-нибудь старушку, чем самому заработать - это да, не поспоришь. Но, опять же, правильно ли это? Не думаю.

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


Выше сказано лишь то, что кто-то не разбирается в поставленном вопросе и делает из этого какие-то выводы (особенно забавно читать про "захлёбывание" было). Про все "крупные геймплеи" говорить бессмысленно, ибо достаточно взглянуть на остальной код, чтоб понять как они написаны (и речь не о том, что авторы плохие и написали всё плохо, а о том, что эти скрипты начинали писаться очень давно и тогда о подобном особо не думали (чтоб это понять, достаточно лишь на официальный форум зайти и почитать темы ~2010 года. Там и stock быстрее pubic, и массивы лучше объявлять в 512 ячеек. а не 1024, ибо это оптимизированнее, и много всего ещё весёлого, от чего потом долгое время избавлялись на этом форуме). Не всегда "крупное" означает "хорошо написанное". Смотреть нужно не на написанные моды, а на теорию, в которой объясняется принцип работы. И уже исходя из этого делать выводы). А тебя я хочу поздравить с тем, что ты потратил в 3 раза больше памяти (ну или сколько у тебя массивов) и получил из этого ровным счётом ни-че-го хорошего. Ну кроме упоения своей лени.

Какие к черту в 3 раза больше памяти? Добавление памяти напрямую в сегмент данных, эквивалентно добавлению памяти к стэку. Я не потрачу лишней памяти. Лишняя память будет уходить в твоем случае (по скольку память придется выделять под каждую новую букву). А память из стэка будет более рациональна использована.
Какие к черту "старые моды"? В старых модах, наоборот таки, использовался твой вариант с локальным массивом на все случае жизни, только они, как правило, ничего не считали и выделяли везде 256 ячеек. Я говорю про современные моды, сегодняшних гигантов, открой исходники гамбита и что мы там увидим? Мой вариант, который я предлагал выше:


new
g_small_string [ 256 ],
g_string [ 1024 ],
g_big_string [ 2048 ];

Конечно, тут абсурдная трата памяти, но чем не вариант.


Серьёзно. Ты тут не на сервер поиграть зашёл, а пишешь скрипты. И "тяп-ляп" делать не получится. Очень многое в программировании придумано для того, чтоб тебя обезопасить от лишних ошибок. Тот же Pawn, на котором ты пишешь, для того и был придуман.
И никто не называет это главным плюсом. Используя локальные массивы, ты, как минимум:
1) Не тратишь лишнюю память в сегменте данных (а стэк, я напомню, является лишь частью этого сегмента данных и выделенная под стэк память никуда не исчезнет, если вы не будете его использовать)
2) Делаешь код логичнее и читабельнее (по инициализации видно, что дальше в коде используется массив на такое-то количество ячеек)
3) Как я уже писал ранее, избавляешься от возможности допустить ошибку (мной описанный случай - не единственный. Так же можно не обнулить массив, например, где-нибудь в цикле, в котором идёт форматирование и на выходе получить кашу из текста при многократном использовании кода). В перспективе это сэкономит в разы больше времени, нежели если ты будешь тратить на подсчёт и объявление этого массива

Не буду говорить лишних слов, просто прокомментирую "плюсы" которые ты назвал:

1) А стэк не находится в сегменте данных? Ты тратишь такую же память сегмента данных, только выделенную под стэк, при этом потратишь еще больше, добавляя памяти в стэк. И кажется, я уже об этом говорил. На всякий случае повторю, что способ с локальных массивами в итоге потратит намного больше памяти, чем 2 - 3 массива на все случае. Думаю говорить почему не нужно, да?
2) Когда код засорен инициализацией нового массива при каждом формате - такая себе логичность и читабельность. А если у тебя есть выделенный под формат отдельный массив, и назван подобающе - ты сразу понимаешь почему и зачем. И для этого не нужно овер999 массивов в одном участке кода.
3) Если ты единственный разработчик геймплея - еще один сомнительный "плюс", если разработчиков много - я говорил выше, что в таких модах нужно писать автономные участки кода, что бы скриптеру не приходилось собирать одну систему из всего мода. Но таких модов нет, ведь все моды пишутся "для себя", как правило, одним человеком.


А теперь прочти тему до конца, если не понимаешь как работают эти самые массивы, и пойми, что если ты не создашь однажды массив в 4к ячеек, ничто не "захлебнётся". Хотя, если судить по написанному тобой, складывается впечатление, что ты не очень сильно паришься по поводу того, как написан твой код и какова его структура. С таким подходом да, у тебя там всё рано или поздно захлебнётся.
Да и повторю ещё раз: стэк - тот же глобальный массив. От того, что ты увеличишь его, ничего не изменится и хуже не станет. Уж лучше прибавить немного к стэку и использовать прошлые 4к ячеек, что были в нём, чем создавать ещё один массив, выделяя дополнительные 4к ячеек.

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

DeimoS
02.01.2018, 16:03
А с каких ты решаешь "как правильно"? Есть два варианта способных на жизнь, и какой из них "правильный" - каждый решает для себя сам. Ты сейчас утверждаешь "как тебе удобнее" - поэтому твои слова, ничем не отличаются от моих слов.

Решаю не я, а документация и логика, которую вложили в реализацию стэка и кучи. Тебе уже дали глобальный массив и позволили удобно резервировать отдельные его части под свои нужды, а ты берёшь и лепишь ещё один массив, делая всё то же самое, только вручную, решая все проблемы, что за тебя уже решили, прописав логику стэка. Вот отсюда и выходит, что мой способ является "правильным", не?
А то, что вариант с глобальными переменными имеет право на жизнь и поддерживается определённым числом людей, не говорит о том, что он правильный.



Лолчто?

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

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


Я не потрачу лишней памяти.

Ну вот скинь результаты компиляции твоего скрипта. И посмотрим сколько стэка у тебя весит мёртвым грузом


Лишняя память будет уходить в твоем случае (по скольку память придется выделять под каждую новую букву). А память из стэка будет более рациональна использована.

Под какую каждую новую букву?
Ну а про рациональное использование я выше написал: скинь результат компиляции своего скрипта и посмотрим как рационально ты используешь её.





Какие к черту "старые моды"? В старых модах, наоборот таки, использовался твой вариант с локальным массивом на все случае жизни, только они, как правило, ничего не считали и выделяли везде 256 ячеек. Я говорю про современные моды, сегодняшних гигантов, открой исходники гамбита и что мы там увидим? Мой вариант, который я предлагал выше:


new
g_small_string [ 256 ],
g_string [ 1024 ],
g_big_string [ 2048 ];

Конечно, тут абсурдная трата памяти, но чем не вариант.

Эмм, а что, твой гамбит был на прошлой неделе написан за пару часов? -_-
И ты лишь подтвердил мои слова



1) А стэк не находится в сегменте данных? Ты тратишь такую же память сегмента данных, только выделенную под стэк

Разница лишь в том, что:
1) Память под стэк в любом случае будет выделена: используешь ты её или нет (можно, конечно, уменьшить размер стэка, но... перейдём ко второму пункту)
2) В стэке уже заложена логика обработки данных (очищение памяти после использования, например) и исправлено множество проблем (зона видимости переменных)
Создавая глобальные массивы, ты создаёшь тот же самый стэк, только перекладываешь на свою голову контроль за содержимым массивов. Что ты этим выиграешь?
Чуть меньше символов нужно будет писать? Да. Только взамен тебе придётся самостоятельно следить за собой, дабы не допустить те ошибки, что я в предыдущих сообщениях описывал. И потом отлавливать баги.
Твой вариант удобен только при оценке на короткий промежуток времени. В перспективе твой вариант лишь больше проблем создаст и не более того.


при этом потратишь еще больше, добавляя памяти в стэк

Да что ты привязался к этому добавлению? Ты сначала заполни стэк, а потом уже добавляй. Да и каким боком я потрачу больше-то? Иди и разберись как работает стэк, прежде чем писать такой бред.


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

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


2) Когда код засорен инициализацией нового массива при каждом формате - такая себе логичность и читабельность. А если у тебя есть выделенный под формат отдельный массив, и назван подобающе - ты сразу понимаешь почему и зачем. И для этого не нужно овер999 массивов в одном участке кода.

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




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

О каком существенном потреблении памяти идёт речь? -_- Ты что курил? Для начала изучи то, как работает стэк (хотя в первых сообщениях я и так всё описывал. И даже из тех моих объяснений становится понятно, что ты пишешь чушь), прежде чем писать подобный бред. Или же покажи что именно ты имеешь ввиду и посмотрим насколько твои суждения верны

encoder
03.01.2018, 14:25
Какие к черту в 3 раза больше памяти? Добавление памяти напрямую в сегмент данных, эквивалентно добавлению памяти к стэку. Я не потрачу лишней памяти. Лишняя память будет уходить в твоем случае (по скольку память придется выделять под каждую новую букву). А память из стэка будет более рациональна использована.
Какие к черту "старые моды"? В старых модах, наоборот таки, использовался твой вариант с локальным массивом на все случае жизни, только они, как правило, ничего не считали и выделяли везде 256 ячеек. Я говорю про современные моды, сегодняшних гигантов, открой исходники гамбита и что мы там увидим? Мой вариант, который я предлагал выше:


new
g_small_string [ 256 ],
g_string [ 1024 ],
g_big_string [ 2048 ];

Конечно, тут абсурдная трата памяти, но чем не вариант.


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