PDA

Просмотр полной версии : [Вопрос] 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

DeimoS
28.01.2017, 12:31
crashdetect молчит?
Покажи сам массив-то.
И пробовал вместо strins использовать format?

ziggi
28.01.2017, 17:13
Думаю, что проблема глобальная - возможно проблемы со стеком или что-то вроде этого. Покажи вывод компилятора после компиляции.

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[]; везде

StevenH
29.01.2017, 14:20
А он чем то плох? Я не заморачиваюсь написанием 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
А ты мне можешь объяснить причину? Зачем два раза выделять память? Если бы все так делали, то бы игры ОЗУ жрали куда больше...

DeimoS
30.01.2017, 07:31
А ты мне можешь объяснить причину? Зачем два раза выделять память? Если бы все так делали, то бы игры ОЗУ жрали куда больше...

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

Пельмень
30.01.2017, 21:30
А ты мне можешь объяснить причину? Зачем два раза выделять память? Если бы все так делали, то бы игры ОЗУ жрали куда больше...

Уровень создания игр в 2к17 и павн версии 2к6 года.
Количество ОЗУ на домашних ПК в 2к6 и в 2к17.
Только задумайся, прошло 11 лет

[ForD]
30.01.2017, 22:16
Уровень создания игр в 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 годов, точно, точно, наверное для того чтобы хватило оперативки

[ForD]
31.01.2017, 18:34
256 =D

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 к примеру). В остальном как-бы действительно ничего от этого не будет, но это довольно необычно.
Для многих проще выделить память тогда, когда она будет нужна и именно столько, сколько её будет нужно (особенно с тенденцией некоторых всё время что-то паковать... наверное, игроков удивить хотят либо с тапка сервер запускают)

qwezert
01.02.2017, 11:56
Не использую глобальные массивы под строки только чисто потому что неудобно потом искать их и нужно всегда следить за тем что бы он был пуст перед очередным форматированием. Просто удобнее создавать и тут же форматировать что бы не теряться.

KrutoyKrosch
02.02.2017, 02:25
format чистит массив сам... а strcat и перехватить можно

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


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

Можно поподробней?