Просмотр полной версии : [Вопрос] Pawn и butterfly
KrutoyKrosch
28.01.2017, 04:25
Попал в очень интересную ситуацию. Дело в том, что каким то неведанным образом у меня изменяется слово в массиве (точнее не в массиве, но я хз как тут выразиться)....
Вот например код:
format(gstring, sizeof(gstring), "Камера создана. ID %d.", ArryIDAddCamersM1{playerid});
SPN(playerid, gstring);
В чат выводит:
бтотаасоздана. ID %d.
А вот если перед format добавить другую функцию которая работает со строками, например printf
printf("11 - %f %f %f %d\n", PosAddCamersM1[3][ArryIDAddCamersM1{playerid}][playerid],
PosAddCamersM1[4][ArryIDAddCamersM1{playerid}][playerid],
PosAddCamersM1[5][ArryIDAddCamersM1{playerid}][playerid],
ArryIDAddCamersM1{playerid});
format(gstring, sizeof(gstring), "Камера создана. ID %d.", ArryIDAddCamersM1{playerid});
SPN(playerid, gstring);
То в чат выведет нормальное сообщение "Камера создана. ID 0.", а вот в консоль кое что интересное:
бтотааf 133.989959 -58.971668 1093379694
Опять мы видим "бтотаа", так вот мне интересно узнать, каким это собственно образом происходит это?
Если что функция SPN:
stock SPN(playeid, format[])
{
static const
str[] = "{3D8EFF}| Оповещение {FFFFFF}";
strins(format, str, 0, strlen(format) - 1);
return SendClientMessage(playeid, -1, format);
}
И если опять выполнить это действие, то потом уже выводит не "бтотаа", а другие рандомные буквы (или выведет как положено).
- - - Добавлено - - -
Потом еще очень интересный момент, к объекту креплю текст со спец символом (ну то есть эти значки), а оно то выведет нормально, то вот такая хрень... То есть опять по какой то причине идет подмена текста...
https://pp.vk.me/c626129/v626129947/4dec6/bo5LEma7Z84.jpg
https://pp.vk.me/c626129/v626129947/4ded0/W2qDB-kFL_A.jpg
crashdetect молчит?
Покажи сам массив-то.
И пробовал вместо strins использовать format?
Думаю, что проблема глобальная - возможно проблемы со стеком или что-то вроде этого. Покажи вывод компилятора после компиляции.
KrutoyKrosch
28.01.2017, 19:12
crashdetect молчит.
Если про gstring, то глобально через new.
Поменял и стало нормально... Получается проблема в strins?
stock SPN(playeid, _format[])
{
static const
str[] = "{3D8EFF}| Оповещение {FFFFFF}";
new
string[sizeof(str) + 128];
format(string, strlen(string) - 1, "%s%s", str, _format);
return SendClientMessage(playeid, -1, string);
}
Ты про это?
Pawn compiler 3.10.20160907 Copyright (c) 1997-2006, ITB CompuPhase
Header size: 1668 bytes
Code size: 54148 bytes
Data size: 1587452 bytes
Stack/heap size: 16384 bytes; estimated max. usage=195 cells (780 bytes)
Total requirements: 1659652 bytes
- - - Добавлено - - -
А вот сегодня вообще выводит не "бтотаа", а вот что в консоль:
куда будет смотреть камера.
Хотя я вывожу совсем другое....
printf("%f %f %f %d\n", PosAddCamersM1[3][ArryIDAddCamersM1{playerid}][playerid],
PosAddCamersM1[4][ArryIDAddCamersM1{playerid}][playerid],
PosAddCamersM1[5][ArryIDAddCamersM1{playerid}][playerid], ArryIDAddCamersM1{playerid});
Daniel_Cortez
28.01.2017, 19:45
Функцию strins лучше избегать, т.к. она не учитывает размер массива, в который производится запись (баг исправлен только в Pawn 4.0). Если полученная строка больше, чем сам массив, то функция запишет лишние символы за пределы массива - возможно, в другой массив, который располагается следующим в памяти. Скорее всего, этим и объясняется то, что показано на скриншотах.
Пельмень
28.01.2017, 20:29
Щас бы в 2к17 глобальный массив для строк юзать
KrutoyKrosch
28.01.2017, 21:35
Щас бы в 2к17 глобальный массив для строк юзать
А он чем то плох? Я не заморачиваюсь написанием new string[]; везде
А он чем то плох? Я не заморачиваюсь написанием new string[]; везде
Ууу... Лучше создавать каждый раз новый стринг, чем использовать один глобальный...
Неправильный пример (так категорически не стоит использовать):
new gstring[128];
// где то в команде
format(gstring, sizeof(gstring), "Привет %s", GetName(playerid));
SCM(playerid, -1, gstring);
// где то во второй команде
format(gstring, sizeof(gstring), "Твой левел - %d, nick - %s", ...);
SCM(playerid, -1, gstring);
Куда лучше использовать так:
// где то в команде
new string[32];
format(string, sizeof(string), "Привет %s", GetName(playerid));
SCM(playerid, -1, string);
// где то во второй команде
new string[49];
format(string, sizeof(string), "Твой левел - %d, nick - %s", ...);
SCM(playerid, -1, string);
KrutoyKrosch
30.01.2017, 05:16
А ты мне можешь объяснить причину? Зачем два раза выделять память? Если бы все так делали, то бы игры ОЗУ жрали куда больше...
А ты мне можешь объяснить причину? Зачем два раза выделять память? Если бы все так делали, то бы игры ОЗУ жрали куда больше...
Я ничего не хочу сказать и не осуждаю использование глобального массива (хоть и сам никогда не буду таким извращением заниматься), но твоё заключение про двойное выделение память - это...
В общем, тебе стоит ознакомиться с принципами работы стэка
Пельмень
30.01.2017, 21:30
А ты мне можешь объяснить причину? Зачем два раза выделять память? Если бы все так делали, то бы игры ОЗУ жрали куда больше...
Уровень создания игр в 2к17 и павн версии 2к6 года.
Количество ОЗУ на домашних ПК в 2к6 и в 2к17.
Только задумайся, прошло 11 лет
Уровень создания игр в 2к17 и павн версии 2к6 года.
Количество ОЗУ на домашних ПК в 2к6 и в 2к17.
Только задумайся, прошло 11 лет
Прошло 11 лет, нечего не изменилось....
Disinterpreter
31.01.2017, 17:49
Сейчас сервера имеют большой объем ОЗУ. Вам 4гб хватит :D Можно и по 3 раза память выделить.
Пельмень
31.01.2017, 17:49
;81992']Прошло 11 лет, нечего не изменилось....
То то я смотрю, у тебя компьютер с 128 mb RAM, да и игры, конечно же, у нас сейчас на движках, которые не обновлялись с 2006 годов, точно, точно, наверное для того чтобы хватило оперативки
Nexius_Tailer
31.01.2017, 18:41
Ууу... Лучше создавать каждый раз новый стринг, чем использовать один глобальный...
Неправильный пример (так категорически не стоит использовать):
new gstring[128];
// где то в команде
format(gstring, sizeof(gstring), "Привет %s", GetName(playerid));
SCM(playerid, -1, gstring);
// где то во второй команде
format(gstring, sizeof(gstring), "Твой левел - %d, nick - %s", ...);
SCM(playerid, -1, gstring);
Куда лучше использовать так:
// где то в команде
new string[32];
format(string, sizeof(string), "Привет %s", GetName(playerid));
SCM(playerid, -1, string);
// где то во второй команде
new string[49];
format(string, sizeof(string), "Твой левел - %d, nick - %s", ...);
SCM(playerid, -1, string);
"Ууу..." мало что аргументирует)
KrutoyKrosch, в основном плохо это только тем, что вероятность сбиться и случайно вывести не тот текст больше, особенно если в этот массив записывается что-то без его предварительной очистки (strcat к примеру). В остальном как-бы действительно ничего от этого не будет, но это довольно необычно.
Для многих проще выделить память тогда, когда она будет нужна и именно столько, сколько её будет нужно (особенно с тенденцией некоторых всё время что-то паковать... наверное, игроков удивить хотят либо с тапка сервер запускают)
Не использую глобальные массивы под строки только чисто потому что неудобно потом искать их и нужно всегда следить за тем что бы он был пуст перед очередным форматированием. Просто удобнее создавать и тут же форматировать что бы не теряться.
KrutoyKrosch
02.02.2017, 02:25
format чистит массив сам... а strcat и перехватить можно
- - - Добавлено - - -
Я ничего не хочу сказать и не осуждаю использование глобального массива (хоть и сам никогда не буду таким извращением заниматься), но твоё заключение про двойное выделение память - это...
В общем, тебе стоит ознакомиться с принципами работы стэка
Можно поподробней?
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot