Просмотр полной версии : crash ошибка при больших индексах массива
Согласно документации, максимальное число элементов в одномерном массиве: 2^32=4294967296. Мне нужен весь диапазон индексов. Пробуем:
var arr:Array=new Array();
arr[0]=false;
// ... и др.
arr[2147483647]=true;
arr[2147483648]=true; // с этого индекса начинаются проблемы
arr[3273124597]=true;
arr[4294967295]=true;
Cобственно проблемы:
arr.splice(0); // вызывает неуправляемую утечку памяти с crash ошибкой плейера:
Add-ons: {972ce4c6-7e08-4474-a285-3208198ce6fd}:3.0.13
BuildID: 2009073022
CrashTime: 1251135034
InstallTime: 1249678458
ProductName: Firefox
SecondsSinceLastCrash: 1950
StartupTime: 1251134999
Theme: classic/1.0
Vendor: Mozilla
Version: 3.0.13
---------------------------------------
Подозрительный момент: во Flex'овом отладчике по watch видно, что все элементы, начиная с индекса 2147483648 он [отладчик] в 'Expressions' окне отрисовывает уже без квадратных скобок, т.е. выглядит это так:
[2147483647]=true;
2147483648=true;
3273124597=true;
4294967295=true;
Однако обращения к элементам с этими индексами проходят удачно и значения считываются.
Использую SDK 3.3.0.
Объем памяти: 2Гб.
Это баг или я что-то не так понимаю?
trace(2147483648, int.MAX_VALUE);
Интересно, в какой ситуации нужен такой большой массив?
Да, и это, ссылку на документацию пожалуйста, как это свойсто length типа int будет вам возвращать такие числа?
trace(2147483648, int.MAX_VALUE);
Да, и это, ссылку на документацию пожалуйста, как это свойсто length типа int будет вам возвращать такие числа?
Хм. Да нормально возвращают. И отладчик, и трассировщик::
var tn:Number=arr.length;
trace(tn);
Да, и это, ссылку на документацию пожалуйста, как это свойсто length типа int будет вам возвращать такие числа?
Не int, а uint.
http://livedocs.adobe.com/flex/3/html/help.html?content=Part6_ProgAS_1.html
@ udaaff:
Array(numElements:int = 0)
Lets you create an array of the specified number of elements.
То что у length стоит тип uint, это для проформы, на самом деле int.
@ microed:
Это ссылка на титульную страницу...
Вам на самом деле сюда надо было сначала смотреть:
http://livedocs.adobe.com/flex/3/langref/Array.html
@ wvxvw
Indexed arrays use an unsigned 32-bit integer for the index number. The maximum size of an indexed array is 232 - 1 or 4,294,967,295. An attempt to create an array that is larger than the maximum size results in a run-time error.
Там int, тут uint.. не понятно.
@ udaaff:
То что у length стоит тип uint, это для проформы, на самом деле int.
@ microed:
Это ссылка на титульную страницу...
Вам на самом деле сюда надо было сначала смотреть:
http://livedocs.adobe.com/flex/3/langref/Array.html
Ну хорошо, смотрим..
"Property Detail
length:uint
A non-negative integer specifying the number of elements in the array." И далее по тексту..
"The uint data type is stored internally as a 32-bit unsigned integer and comprises the set of integers from 0 to 4,294,967,295"
Пока всё в документации указывает на index max = 4,294,967,295. Чем докажете, что это всё "для проформы"? Они где-то оговорились или покаялись?
Хм... а вообще - интересный момент... не смотря на то, что аргумент у Array() задан как int, он вполне принимает и бОльшие значения...
Возможно зависит от версии плеера, потому что у меня ваш код не вызывает никаких исключений.
Для прогонки использую плагин для firefox v10.0 r12. На нем и проявилось..
var array:Array = new Array(0xFFFFFFFF); // все нормально
var array:Array = new Array(0xFFFFFFFF + 1);
RangeError: Error #1005: Array index is not a positive integer (4294967296).
at Error$/throwError()
at Array()
at Test()[F:\workspaces\Flex Builder\test\src\Test.as:13]
upd:
Код из первого поста, никаких ошибок не вызывает.
Подозрительный момент: во Flex'овом отладчике по watch видно, что все элементы, начиная с индекса 2147483648 он [отладчик] в 'Expressions' окне отрисовывает уже без квадратных скобок, т.е. выглядит это так:
[2147483647]=true;
2147483648=true;
3273124597=true;
4294967295=true;
Однако обращения к элементам с этими индексами проходят удачно и значения считываются.
Использую SDK 3.3.0.
Объем памяти: 2Гб.
Это баг или я что-то не так понимаю?
Просто кода идет обращение к динамическим свойствам, то строка и число взаимозаменимы, а поскольку массив динамический объект, то при попытке обратится к свойству, которое не может быть индексом, имя свойства будет расценено как строка, вот поэтому вы и наблюдаете то, что наблюдаете.
Но, пока не понятно, баг ли это конкретной версии плеера или документации. Быстрый поиск по списку багов ничего такого не нашел... предлагаю попробовать в другой версии плеера (есть и десятка по-новее, и можно последнюю девятку), если там такого не наблюдается - значит баг плеера...
EDIT:
// SDK 4.0 4904
// SDK 4.0 head revision (9546)
var arr:Array = [];
arr[uint.MAX_VALUE + 2] = true;
trace(Capabilities.version);
trace(arr[uint.MAX_VALUE + 2], uint.MAX_VALUE, arr.length);
//WIN 10,0,22,87
//true 4294967295 0
// Flash IDE
var arr:Array = [];
arr[uint.MAX_VALUE + 2] = true;
trace(Capabilities.version);
trace(arr[uint.MAX_VALUE + 2], uint.MAX_VALUE, arr.length);
//WIN 9,0,115,0
//true 4294967295 0
var array:Array = new Array(0xFFFFFFFF); // все нормально
var array:Array = new Array(0xFFFFFFFF + 1);
RangeError: Error #1005: Array index is not a positive integer (4294967296).
at Error$/throwError()
at Array()
at Test()[F:\workspaces\Flex Builder\test\src\Test.as:13]
upd:
Код из первого поста, никаких ошибок не вызывает.
Сам код создания большого массива ошибок не вызывает. Ошибку вызывает зачистка этого массива. Теперь попробуй сделать:
arr.splice(0); // here bug
Добавлено через 16 минут
Сделал тест код с контролем текущего времени и использованной памяти.
К примеру, простая вещь:
var arr:Array=new Array();
arr[10000000]=true;
arr.splice(0);
вызывает кратковременный всплеск потребляемой памяти на ~38MB
а с увеличением индекса на порядок:
var arr:Array=new Array();
arr[100000000]=true;
arr.splice(0);
получаем всплекс на ~382MB ..ну и т.д. Использование памяти можно посмотреть и в диспетчере задач - показывает тоже самое.
Видно, что временное потребление памяти растет линейно. Что уж говорить про максимальный индекс [4294967295].
Насчет времени: когда производится очистка массива, выполнение пользовательского кода останавливается - тормозится даже Timer и листинеры.
А порядок задержки опять же зависит от наибольшего используемого значения индекса, даже если элемент в массиве один.
В общем, не баг это, а отвратно написанная внутренняя системная функция очистки массива.
Еще раз про максимальный индекс - другий более простой способ, чо это int.MAX_VALUE:
var a:Array = [];
a[uint.MAX_VALUE] = true;
a.length = 0;
trace(a[uint.MAX_VALUE]); // true
что еще рз подтверждает, что значения больше int.MAX_VALUE не могут быть индексами в массиве.
..что еще раз подтверждает сырость продукта, ибо если "значения больше int.MAX_VALUE не могут быть индексами в массиве", то мы должны ясно и недвусмысленно получать в дыню:
RangeError: Error #1005
ан нет...
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.