Добро пожаловать на Pro Pawn - Портал о PAWN-скриптинге.
Показано с 1 по 6 из 6
  1. #1
    Аватар для Sersoftin
    Пользователь

    Статус
    Оффлайн
    Регистрация
    16.08.2014
    Адрес
    Rostov-on-Don
    Сообщений
    29
    Репутация:
    8 ±

    Почему не стоит возвращать строки в вызываемых функциях?

    В процессе написания мода я решил пойти на такую крайность: вернуть значение строки в 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;
    }
    И ничего особенного не заметил. Все отработало корректно. Так как же вызвать переполнение стека возвратом стринга?
    Последний раз редактировалось DeimoS; 30.10.2014 в 12:10.
    Yummy Role Play forever!

  2. #2
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    А верните не 24 ячейки, а, например, 2048
    PHP код:
    main()
    {
        new 
    dest[2048];
        
    dest get_crash();
        print(
    dest);
    }

    stock get_crash()
    {
        new 
    src[2048] = "Этот код заставит сервер вывести ошибку Runtime Error";
        return 
    src;

    и подключите crashdetect.

    И да, ник уже давно все получают в OnPlayerConnect, а далее вызывают массив, в котором этот ник записан
    Связаться со мной в VK можно через личные сообщения этой группы
    Заказы не принимаю

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  3. #3
    Аватар для #ball
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.06.2014
    Адрес
    Rostov-on-Don
    Сообщений
    119
    Репутация:
    14 ±
    И да, ник уже давно все получают в OnPlayerConnect, а далее вызывают массив, в котором этот ник записан
    Это понятно,пример был взят с темы об оптимизации.
    PHP код:
    main()
    {
        new 
    dest[2048];
        
    dest get_crash();
        print(
    dest);
    }

    stock get_crash()
    {
        new 
    src[2048] = "Этот код заставит сервер вывести ошибку Runtime Error";
        return 
    src;

    Ну а зачем возвращать такое огромное число ячеек,врид ли такое где то будет.Если поставить не 2048,а 128,то все отлично работает и без ошибок.
    Последний раз редактировалось #ball; 30.10.2014 в 11:23.

  4. #4
    Аватар для MR_BEN
    Пользователь

    Статус
    Оффлайн
    Регистрация
    10.01.2014
    Сообщений
    110
    Репутация:
    29 ±
    Это если один такой сток, а если их будет больше?

  5. #5
    Аватар для DeimoS
    Модератор?

    Статус
    Оффлайн
    Регистрация
    27.01.2014
    Адрес
    Восточный Мордор
    Сообщений
    5,588
    Репутация:
    1984 ±
    Цитата Сообщение от #ball Посмотреть сообщение
    Ну а зачем возвращать такое огромное число ячеек,врид ли такое где то будет.Если поставить не 2048,а 128,то все отлично работает и без ошибок.
    Ну хорошо, сделай так:
    PHP код:
    main()
    {
        new 
    dest[4070];
        
    PlayerName();
        print(
    dest);
    }
    stock PlayerName()
    {
        new 
    pname[MAX_PLAYER_NAME];
        
    pname "Azaza";
        return 
    PlayerName;

    И посмотри на количество занятого стэка (если не установлен режим отладки, то перед этим зайди в папку с pawno и создай там файл "pawn.cfg", в котором пропиши "-d3" и после уже компилируй).
    А после
    PHP код:
    return PlayerName
    замени на
    PHP код:
    return 1
    И опять посмотри.

    С возвратом единицы в стэке будет занято 4105 ячейки (4105*4 = 16420 байт), а с возвратом массива уже будет занято 4130 (4130*4 = 16520 байт).
    То есть, если ты возвращаешь массив, он в стэке занимает в 2 раза больше места (сначала в стоке создаётся, а после в функции, где вызывается сток, резервируется столько же памяти, дабы вернувшийся результат было где хранить).
    Если ты будешь это всё делать в new.pwn, где у тебя будет лишь один массив на 100 ячеек и сток с массивом в 50 ячеек, которые ты будешь возвращать, проблем, естественно, не будет. Но если у тебя будет целый мод, в котором создано уже с десяток массивов в одном лишь OnGameModeInit, а ты там ещё и десяток возвратов сделаешь... Сам понимаешь, стэк очень быстро кончится

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

    Цитата Сообщение от #ball Посмотреть сообщение
    Это понятно,пример был взят с темы об оптимизации.

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

    Широко известно, что идеи стоят 0.8333 цента каждая (исходя из рыночной цены 10 центов за дюжину).
    Великих идей полно, на них нет спроса.
    Воплощение идеи в законченную игру требует долгой работы,
    таланта, терпения и креативности, не говоря уж о затратах денег, времени и ресурсов.
    Предложить идею просто, воплотить – вот в чём проблема

    Steve Pavlina

  6. Пользователь сказал cпасибо:
    #ball (30.10.2014)
  7. #6
    Аватар для #ball
    Пользователь

    Статус
    Оффлайн
    Регистрация
    01.06.2014
    Адрес
    Rostov-on-Don
    Сообщений
    119
    Репутация:
    14 ±
    Цитата Сообщение от DeimoS Посмотреть сообщение
    Ну хорошо, сделай так:
    PHP код:
    main()
    {
        new 
    dest[4070];
        
    PlayerName();
        print(
    dest);
    }
    stock PlayerName()
    {
        new 
    pname[MAX_PLAYER_NAME];
        
    pname "Azaza";
        return 
    PlayerName;

    И посмотри на количество занятого стэка (если не установлен режим отладки, то перед этим зайди в папку с pawno и создай там файл "pawn.cfg", в котором пропиши "-d3" и после уже компилируй).
    А после
    PHP код:
    return PlayerName
    замени на
    PHP код:
    return 1
    И опять посмотри.

    С возвратом единицы в стэке будет занято 4105 ячейки (4105*4 = 16420 байт), а с возвратом массива уже будет занято 4130 (4130*4 = 16520 байт).
    То есть, если ты возвращаешь массив, он в стэке занимает в 2 раза больше места (сначала в стоке создаётся, а после в функции, где вызывается сток, резервируется столько же памяти, дабы вернувшийся результат было где хранить).
    Если ты будешь это всё делать в new.pwn, где у тебя будет лишь один массив на 100 ячеек и сток с массивом в 50 ячеек, которые ты будешь возвращать, проблем, естественно, не будет. Но если у тебя будет целый мод, в котором создано уже с десяток массивов в одном лишь OnGameModeInit, а ты там ещё и десяток возвратов сделаешь... Сам понимаешь, стэк очень быстро кончится

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



    И да. Не говори гоп, пока не перепрыгнешь. Нужды бывают разные и если ты с таким ещё не столкнулся - не значит, что такого не может быть
    Благодарю за ответ.Все понял)
    Последний раз редактировалось DeimoS; 30.10.2014 в 12:09.

 

 

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •