Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Регистрация Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Блоги > Идиотизмы

Даже в определениях идиотизма встречается идиотизм.
Цитата:
Идиотизм — устаревшее название идиомы
Идиома в программировании — понятие близкое к понятию шаблона проектирования. Идиомы представляют собой шаблоны проектирования, учитывающие специфику конкретного языка программирования и потому не универсальные. Это хорошие решения проектирования для конкретного языка или программной платформы.
Рейтинг: 5.00. Голосов: 2.

Идиотизмы: не ByteArray а мусорка

Запись от BlooDHounD размещена 29.06.2010 в 02:07
Обновил(-а) BlooDHounD 02.07.2010 в 05:06

для понимания материала необходимы следующие знания:
flash.utils.ByteArray


сижу я, значит, пишу обновлении для своей крипто-библиотеки, и случайно вывожу на экран 2 результата от 2 запусков PNGEncoder.
первый вариант 100% совпадает с оригиналом, а второй был слегка искажён. я сперва не сообразил, что произошло, а потом пришёл в состояние шока. решил добавить ещё парочку результатов, и получил, ещё более искажённые результаты.

Название: Безымянный.jpg
Просмотров: 2602

Размер: 28.7 Кб

начал искать искать ошибки у себя в коде: переиспользование переменных; проверял везде ли чиститься память; заменял одни вызовы другим, но результат становился чаще хуже, чем лучше.
на протяжении всех 10 часов паники я общался с wvxvw, и мы вместе пытались понять причину, но не ничего не выходило.

в конце концов в один из блоков я вставил код проверки на записанное значение в ByteArray. и оказалось, что там на 88731 индексе уже записано число отличное от 0.
глаза мои вылезли на орбиту: ведь этот массив был создан всего 2мя строчками выше, и в него ничего не писалось кроме одного числа в нулевой индекс! то есть фактически он был пуст.

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

выяснилось следующие: при определённых обстоятельствах бинарник оказывался не девственно чистым. обстоятельства такого поведения обнаружить не удалось. но решение найдено таки было.
чистота бинарника зависит от первой операции проводимой с ним!
если первой операцией будет write, то в массиве может оказаться мусор. но если первой операцией задать ему нужную длину, то на протяжении всей длинны будут записаны только нули.
Код AS3:
var b:ByteArray = new ByteArray();
b.writeUnsignedInt( value );
b.length = 1024; // может попасться мусор
Код AS3:
var b:ByteArray = new ByteArray();
b.length = 1024; // мусора не будет
b.writeUnsignedInt( value );
судя по всему в бинарнике остаются значения от предыдущих вычислений, хоть я в конце каждого использования честно вызываю clear.
Всего комментариев 31

Комментарии

Старый 29.06.2010 12:49 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
Старый 29.06.2010 17:36 TimID вне форума
TimID
 
Аватар для TimID
Я не понимаю, чего Вы удивляетесь, нормальная практика создавать массив простым выделением памяти, ведь так значительно быстрее, чем еще вызывать его очистку.

Вот очистка массива изменением его длины - это забавный баг
Старый 29.06.2010 17:54 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
TimID, как много Вы знаете о работе виртуальных машин =)
Старый 29.06.2010 19:12 PeTa4eK вне форума
PeTa4eK
 
Аватар для PeTa4eK
Глянул ссылку выше. Загрузил main.swf, вот что вижу:



Так и должно быть? ))) Windows 7, никаких артефактов нет...
Старый 29.06.2010 19:25 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
PeTa4eK, Вы везунчик -) если Вы заметили там представлено 2 скриншота с разными результатами. один мой, а второй Олега. swf одна и та же. причём появление артефактов зависит и от картинки. они не каждой картинке у меня появлялись.
Старый 29.06.2010 20:16 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Будет весело если баг в винде...
Кстати сейчас попробую в убунте.
Старый 29.06.2010 20:18 iNils вне форума
iNils
 
Аватар для iNils
В IE в 10.0 все нормально.
В standalone 10.0 - баг
В FF 10.0 - баг
Старый 29.06.2010 20:29 wvxvw вне форума
wvxvw
 
Аватар для wvxvw
Просто для общего сведения, Ubuntu Lucid - никаких визуальных артефактов...
Старый 29.06.2010 20:51 kutuzov вне форума
kutuzov
 
Аватар для kutuzov
win7, 10.1
во всех браузерах (ie, opera, ff, chrome, safari) и стендалоун плеере все ок
Старый 29.06.2010 22:33 dimarik вне форума
dimarik
 
Аватар для dimarik
TimID, теперь Вы должны уже начать догадываться как работают виртуальные машины.
Старый 29.06.2010 23:09 Zebestov вне форума
Zebestov
 
Аватар для Zebestov
Win7
standalone 10.0 баг
IE 10.1 норм
Chrome 10.1 норм

может в 10.1 баг поправили?
Старый 30.06.2010 08:13 PeTa4eK вне форума
PeTa4eK
 
Аватар для PeTa4eK
Возможно, я лично совсем недавно до последней версии обновилсо)
Старый 30.06.2010 10:38 TimID вне форума
TimID
 
Аватар для TimID
2dimarik - не совсем понял замечание. Причем здесь виртуальные машины? Скорее всего флеш-плеер использует менеджер памяти операционной системы при выделении памяти под bytearray, чтобы не заморачиваться с его возможным вылезанием за память, изначально выделенную под переменные. Ведь в этот массив можно сохранить и 100Мбайтный файл. Отсюда и "недосмотр" индусских "горе программеров" из Адоб. Ведь "классический" Цешник всегда принудительно очищает массив перед использованием, значит и не определяет требование его очистить как "защиту от дурака"
Кстати, сильверлайт действует примерно также.
Старый 30.06.2010 13:17 dimarik вне форума
dimarik
 
Аватар для dimarik
BloodHound, верно ли товарищ понимает как работают в. машины?
Старый 30.06.2010 13:59 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
dimarik, ну как тебе сказать, верно или нет =) он вообще о чём-то о своём говорит =)
TimID, 100Мб может и можно, а вот 4гб ну никак не запишешь. или вы никогда не слышали о MemoryError?
Старый 30.06.2010 16:09 alexcon314 вне форума
alexcon314
Win7 (fp 10) : в стандалон и в FF ничего не отображается, только самая первая морда(верхний ряд, крйняя слева). в ие без искажений все.
XP (fp 10) : отображает все и с искажениями (стандалон, опера), в ие все норм.

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

Вы привели пример работы именно своего энкодера? Который со скрытыми операторами?
Наблюдались ли баги в ИЕ?
Старый 30.06.2010 17:00 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
я в браузере не тестил.
первая картинка это оригинал. она создаётся сразу. остальные создаются после того как произойдёт их перегон в пнг, а потом loadBytes
Старый 30.06.2010 18:18 alexcon314 вне форума
alexcon314
Еще вопрос, без участия картинок с енкодером получается воспроизвести такое поведение ByteArray? Т.е. заполнить обычным образом массив и, как вы говорите, loadBytes()?
Мне не очень понятна ваша фраза
Цитата:
судя по всему в бинарнике остаются значения от предыдущих вычислений
Вы один и тот же массив используете для хранения промежуточных результатов (каких?) и для окончательных?
Пусть будет мусор в массиве после какого-то там "аллока", неважно как он происходит, и что? Если в него записать "поверх" что-то, мусор же уйдет? Откуда берется мусор именно на выходе? Его там быть просто не должно, либо вы массив заполняете мусором сами.
Еще такой момент. Симптоматично, что loadBytes() не отрабатывает вообще, как оказывается, такое тоже возможно. Точного механизма этой функции я не знаю, но в его теле присутствует АПИ вызов BitBlt() (под виндами, это фактически отрисовка в окно). Так вот он, что называется, fail. Причины: некорректные парамтеры, что чаще означает указатель вникуда, то бишь неправильно был сформирован (либо вообще не сформирован) буфер, откуда надо было брать данные для отрисовки.

Еще, пнг-кодированное изображение, само собой не отображается в окне как есть, оно перегоняется (не уверен как именно, возможно плеер юзает какой-то чисто свой "нулевый" раскодировщик) в единственнй и неповторимый битмап. А значит мы опять приходим к теме - как же вы все-таки заполняете массив?
Старый 30.06.2010 19:36 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
@alexcon314
Цитата:
Сообщение от alexcon314
без участия картинок с енкодером получается воспроизвести такое поведение ByteArray? Т.е. заполнить обычным образом массив и, как вы говорите, loadBytes()?
а причём тут картинки без енкодера? я что-то вашу мысль совсем не понимаю. или Вы думаете, что бага связана с отображением и loadBytes?
Цитата:
Сообщение от alexcon314
Вы один и тот же массив используете для хранения промежуточных результатов (каких?) и для окончательных?
да. для всех.
Цитата:
Сообщение от alexcon314
Пусть будет мусор в массиве после какого-то там "аллока", неважно как он происходит, и что?
что значит и что? и то.
Цитата:
Сообщение от alexcon314
Если в него записать "поверх" что-то, мусор же уйдет?
а кто Вам сказал, что мне надо каждый байт записывать поверх?
Цитата:
Сообщение от alexcon314
Откуда берется мусор именно на выходе? Его там быть просто не должно, либо вы массив заполняете мусором сами.
спасибо Кэп. Вы код в посте смотрели вообще? там не много. всего шесть строчек.
Цитата:
Сообщение от alexcon314
Еще такой момент. Симптоматично, что loadBytes() не отрабатывает вообще, как оказывается, такое тоже возможно. Точного механизма этой функции я не знаю, но в его теле присутствует АПИ вызов BitBlt() (под виндами, это фактически отрисовка в окно). Так вот он, что называется, fail. Причины: некорректные парамтеры, что чаще означает указатель вникуда, то бишь неправильно был сформирован (либо вообще не сформирован) буфер, откуда надо было брать данные для отрисовки.
не понимаю о чём Вы. спуститесь на Землю. мы тут ByteArray обсуждаем.
Цитата:
Сообщение от alexcon314
Еще, пнг-кодированное изображение, само собой не отображается в окне как есть, оно перегоняется (не уверен как именно, возможно плеер юзает какой-то чисто свой "нулевый" раскодировщик) в единственнй и неповторимый битмап. А значит мы опять приходим к теме - как же вы все-таки заполняете массив?
вас не понятно.
Старый 01.07.2010 13:48 alexcon314 вне форума
alexcon314
Помогите воспроизвести появление мусора.
Код:
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.utils.ByteArray;
	import flash.net.SharedObject;
	public class Main extends Sprite 
	{
		private var b:ByteArray;
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// 
			b = new ByteArray();
			fillData(b, 0xffffff00, 0, 5000, "b1");
			b.clear();// чистим предыдущий филл
			fillData(b, 0x000000ff, 4, 5000,"b2");
		}
		private function fillData(b:ByteArray, value:uint, offset:uint, max:uint, name:String):void
		{
			for (var i:int = 0; i < max; i++)
			{
				b.writeUnsignedInt(value);
				b.position += offset;//пропуск позиций, дабы не забить возможный мусор
			}
			var so:SharedObject = SharedObject.getLocal(name, "/");
			so.data.b = b;
			so.flush();
		}
	}
}
сравнив два файла (b1.sol и b2.sol) я не заметил никакого мусора, там где должны быть нули - там нули, там где их не должно быть - их нет. Что я делаю не так?
ЗЫ файлы смотреть пока плеер не выключен.
ЗЫ Непонятно, так непонятно, фик с ним.
Обновил(-а) alexcon314 01.07.2010 в 13:55
Старый 01.07.2010 14:22 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
я не знаю, что Вы делаете не так, но попробую предположить:
1. раньше я сам мусора такого не встречал.
2. если Вы читали описание бага, в джире, то там написано, что создать простой пример нам не удалось.
3. если Вы смотрели скриншоты, то заметили проявление бага не на первом бинарнике, а маленьком кусочке второго.
4. при этом размер бинарников приблизительно такой width * height * 4. в случаи с собоачками это 90К+ байт, а никак не 5К. при этом мусор появляется на в районе 80К.
5. к тому же мусор появляется не после вызова clear, а после создания нового бинарника. clear - как раз таки обнуляет весь массив.
Старый 01.07.2010 14:38 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
6. запись в бинарник происходит по средстави Virtual Memory API. может быть и это и играет роль.
Старый 01.07.2010 15:29 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
мне таки удалось собрать простой пример, в котором наблюдается бага!!! УРА!
Код AS3:
package { 
 
	import flash.display.Sprite;
	import flash.utils.ByteArray;
 
	public class test extends Sprite {
 
		/**
		 * Constructor
		 */
		public function test() {
			super();
 
			// запускаем многократные тесты
			for ( var i:uint = 0; i<10; i++ ) {
				trace( '================== test ' + i );
				binary_test();
			}
 
		}
 
		private static const LENGTH:uint = 5e3;
 
		private static function binary_test():void {
 
			// создаём новый бинарник
			var bytes:ByteArray = new ByteArray();
 
			bytes.writeUnsignedInt( 10 ); // делаем запись
			bytes.length = LENGTH; // меняем длинну
 
			// проверяем что у нас лежит в бинарнике
			var i:uint = 4;
			do {
 
				if ( bytes[ i ] != 0 ) {
					trace( 'index: ' + i + ', value: ' + bytes[ i ] );
				}
 
			} while ( ++i < LENGTH );
 
			// заполняем бинарник
			i = 4;
			do {
 
				bytes.writeInt( i );
 
				i += 4;
			} while ( i < LENGTH );
 
			bytes.clear(); // чистим
 
		}
 
	}
 
}
Код AS3:
			bytes.writeUnsignedInt( 10 ); // делаем запись
			bytes.length = LENGTH; // меняем длинну
если поменять эти2 строчки местами бага исчезает
Обновил(-а) BlooDHounD 01.07.2010 в 15:36
Старый 01.07.2010 15:47 alexcon314 вне форума
alexcon314
Отлично. То что нужно. Кстати, вертелась мысль - закомментить clear(), Попробовал, трейсов стало заметно меньше. Всего в двух тестах последних и понемногу совсем.
Обновил(-а) alexcon314 01.07.2010 в 15:57
Старый 01.07.2010 16:01 alexcon314 вне форума
alexcon314
Если LENGTH = 5е5 и clear() убрать все вообще чисто .
Старый 01.07.2010 16:05 alexcon314 вне форума
alexcon314
Как ты угадал с 5е3?
5е2-чисто
5е4-чисто
5е5-чисто
5е6-чисто
Старый 01.07.2010 16:10 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
alexcon314, да никак. я сперва сделал 1e6. у меня оутпут свалился от спама. я начал уменьшать, что бы найти минимальный размер повторения. на 10е3 трэйсы были, а на 1е3 не было. ну взял серединку.
Старый 17.11.2010 16:24 alexcon314 вне форума
alexcon314
Всплыло...
Не ахти что, но все же.
Вобщем, механизм выделения памяти под массив байтов примерно такой:
Код:
//баги нет
var b:ByteArray = new ByteArray();// выделяется 4096 байт чистой памяти.
b[0] = 10;
b.lenght = 4096;//это ни на что уже не влияет, память чистая изначально.
Менять строки местами нет смысла - все чисто.
Даже если сделать длину < 4096 - в памяти чисто, опять же потому, что выделена она была таковой.
4096 (0х1000) - это не что иное, как размер страницы памяти в х86-системах. Собственно, плеер и выделяет ее как раз по-странично.
Что будет, если взять число > 4096? Например, 5000?
Ну, как и в первом случае после new ByteArray(); выделится 4096 чистой памяти, произойдет запись (массив инициализирован!). А вот дальше.. тут понятное дело, плеер вынужден будет "прихватить" некоторе количемтво ячеек из другой страницы.., но занулять "прихваченные" байты он не будет. Вроде, все логично.
Возьмем целое кратное 4096, ну, скажем 2*4096. Опять видим мусор, причем на второй странице.
Однако, если делать 10*4096 (20*, 30*...), то ситуация значительно лучше! Мусора практически нет. Почему "практически", а не точно? Видимо, плеерный менеджер памяти, при не особо загруженной памяти не скупится выделять чистые странички. Но, тем не менее, может и грязную подсунуть.
Почему же, если мы делаем сначала b.lenght = <что-то большее нуля>; мусора нет? Ну, тут просто. Менеджер видит, свежий массив (не инициализированный!) с точно заданными размерами и у него "развязаны руки" - он может запросто выделить память заново (ссылка b может быть отмаплена на совсем другой адрес), почистить ее и предоставить для использования.
ЗЫ. Ясен пень, все на деле сложнее, но примерно что-то похожее...
Обновил(-а) alexcon314 17.11.2010 в 16:35
Старый 17.11.2010 16:57 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
ну как бы и так всё понятно )
Старый 26.11.2010 01:55 xdoom вне форума
xdoom
 
Аватар для xdoom
win7x64 везде пучком и без багов
Старый 26.11.2010 03:47 BlooDHounD вне форума
BlooDHounD
 
Аватар для BlooDHounD
у меня не пучком.
 

 


Часовой пояс GMT +4, время: 06:55.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2017, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.