В процесі написання мода я вирішив піти на таку крайність: повернути значення рядка в stock. На цьому форумі є тема оптимізації. Там пишуть, що цього робити не варто і це загрожує переповненням стека. Я хотів би побачити програмний код, який здатний викликати це переповнення поверненням стринга в стоці.
У темі наводиться приклад з отриманням ника гравця. Я зробив таке:
CMD: go (playerid, params [])
for (new i; i<=1000;i++)
print (PlayerName (playerid));
print ( "completed");
>
stock PlayerName (playerid)
new pname [MAX_PLAYER_NAME];
GetPlayerName (playerid, pname, sizeof (pname));
return pname;
>
І нічого особливого не помітив. Все відпрацювало коректно. Так як же викликати переповнення стека поверненням стринга?
А поверніть не 24 осередки, а, наприклад, 2048
stock get_crash ()
new src [2048] = "Цей код змусить сервер вивести помилку Runtime Error";
return src;
>
і підключіть crashdetect.
І так, нік вже давно все отримують в OnPlayerConnect, а далі викликають масив, в якому цей нік записаний
І так, нік вже давно все отримують в OnPlayerConnect, а далі викликають масив, в якому цей нік записаний
Це зрозуміло, приклад було взято з теми про оптимізацію.
stock get_crash ()
new src [2048] = "Цей код змусить сервер вивести помилку Runtime Error";
return src;
>
Ну а навіщо повертати таку величезну кількість осередків, врід таке десь будет.Еслі поставив не 2048, а 128, то все відмінно працює і без помилок.
Це якщо один такий стік, а якщо їх буде більше?
Ну а навіщо повертати таку величезну кількість осередків, врід таке десь будет.Еслі поставив не 2048, а 128, то все відмінно працює і без помилок.
Ну добре, зроби так:
main ()
new dest [4070];
PlayerName ();
print (dest);
>
stock PlayerName ()
new pname [MAX_PLAYER_NAME];
pname = "Azaza";
return PlayerName;
>
І подивися на кількість зайнятого стека (якщо не встановлений режим налагодження, то перед цим зайди в папку з pawno і створи там файл "pawn.cfg", в якому пропиши "-d3" і після вже компілює).
А після
return PlayerName;
заміни на
return 1;
І знову подивися.
З поверненням одиниці в стек буде зайнято 4105 осередку (4105 * 4 = 16420 байт), а з поверненням масиву вже буде зайнято 4130 (4130 * 4 = 16520 байт).
Тобто, якщо ти повертаєш масив, він в стек займає в 2 рази більше місця (спочатку в стоці створюється, а після в функції, де викликається стік, резервується стільки ж пам'яті, щоб повернувся результат було де зберігати).
Якщо ти будеш це все робити в new.pwn, де у тебе буде лише один масив на 100 осередків і стік з масивом в 50 осередків, які ти будеш повертати, проблем, природно, не буде. Але якщо у тебе буде цілий мод, в якому створено вже з десяток масивів в одному лише OnGameModeInit, а ти там ще й десяток повернень зробиш. Сам розумієш, стек дуже швидко скінчиться
Це зрозуміло, приклад було взято з теми про оптимізацію.
Ну а навіщо повертати таку величезну кількість осередків, врід таке десь буде.
І так. Не кажи гоп, поки не перескочиш. Потреби бувають різні і якщо ти з таким ще не зіткнувся - не означає, що такого не може бути
Ну добре, зроби так:
main ()
new dest [4070];
PlayerName ();
print (dest);
>
stock PlayerName ()
new pname [MAX_PLAYER_NAME];
pname = "Azaza";
return PlayerName;
>
І подивися на кількість зайнятого стека (якщо не встановлений режим налагодження, то перед цим зайди в папку з pawno і створи там файл "pawn.cfg", в якому пропиши "-d3" і після вже компілює).
А після
return PlayerName;
заміни на
return 1;
І знову подивися.
З поверненням одиниці в стек буде зайнято 4105 осередку (4105 * 4 = 16420 байт), а з поверненням масиву вже буде зайнято 4130 (4130 * 4 = 16520 байт).
Тобто, якщо ти повертаєш масив, він в стек займає в 2 рази більше місця (спочатку в стоці створюється, а після в функції, де викликається стік, резервується стільки ж пам'яті, щоб повернувся результат було де зберігати).
Якщо ти будеш це все робити в new.pwn, де у тебе буде лише один масив на 100 осередків і стік з масивом в 50 осередків, які ти будеш повертати, проблем, природно, не буде. Але якщо у тебе буде цілий мод, в якому створено вже з десяток масивів в одному лише OnGameModeInit, а ти там ще й десяток повернень зробиш. Сам розумієш, стек дуже швидко скінчиться
І так. Не кажи гоп, поки не перескочиш. Потреби бувають різні і якщо ти з таким ще не зіткнувся - не означає, що такого не може бути
Дякую за ответ.Все зрозумів)