Как отключить проверку границ массивов в IDE

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Адская_Капча
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 60
Зарегистрирован: 28.07.2014 (Пн) 20:22

Как отключить проверку границ массивов в IDE

Сообщение Адская_Капча » 16.06.2016 (Чт) 14:44

Сабж))

Впечатлил в этой теме прием от The Trick выхода из границ массива:
viewtopic.php?f=1&t=50816#p6781939
Для повышения быстродействия, чтобы каждый раз не вызывать GetMem/PutMem. Но хотелось бы, чтобы работало и в IDE тоже. Чтобы был универсальный код, а не пришлось плодить каждый раз по 2 версии для IDE и Native. Да и единственный код поддерживать легче.

Как это лучше следует делать?

1 вариант: найдя указатель SafeArray, просто исправить число элементов массива (cElements, по смещению &H10 от SafeArrayPtr) на большое (через PutMem). Но нужно ли потом обратно возвращать старое число элементов? При освобождении массива в памяти это число элементов играет роль? Если число элементов будет подменено на большое, то и разрушится тоже много памяти, затрагивая чужие области?

2 вариант: в памяти пропатчить функцию _vbaGenerateBoundsError, чтобы сразу был выход из нее.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как отключить проверку границ массивов в IDE

Сообщение The trick » 16.06.2016 (Чт) 16:15

Пропатчить виртуальную машину с соответствующими опкодами. Я кстати делаю такую там будут доступны все опции оптимизации в IDE (выход за границы/переполнения)
UA6527P

Адская_Капча
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 60
Зарегистрирован: 28.07.2014 (Пн) 20:22

Re: Как отключить проверку границ массивов в IDE

Сообщение Адская_Капча » 16.06.2016 (Чт) 16:26

То есть, это будет еще лучше моих вариантов? И не будет самого этого лишнего кода проверки границ в режиме IDE?

Думается, это всяко лучше, чем мои глупые потуги... я не смогу пропатчить виртуальную машину, т.к. нахожусь еще в "колыбельке программирования"...

Тогда Адская капча будет с нетерпением ждать Изображение

Чтобы мы все без вас делали, наш спаситель The Trick! Изображение

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Как отключить проверку границ массивов в IDE

Сообщение Хакер » 16.06.2016 (Чт) 20:11

Нужно использовать только первый метод. Второй метод это жутко грязный подход. Криминал. Расстрел.

Что касается вопроса о влияния значения cElements в момент освобождения памяти — вопрос интересный. Сам процесс уничтожения массива нужно разделить на две фазы.

Первая фаза — это зачистка контента массива. Если это массив объектов, ссылки будут занулены, будет вызван IUnknown::Release. Если это строки, будет вызван SysFreeString для каждого элемента. VariantClear для вариантов. И тому подобное. На эту фазу, безусловно, значение cElements влияет.

Вторая фаза — собственно освобождение региона памяти. Здесь нет однозначного ответа. Большинство реализаций кучи памяти имеет метод «free», который принимает только адрес блока, и не требует указывать размер. Менеджер кучи сам знает и ведёт учёт, какому блоку какой размер соответствует. Обычно этот размер хранится непосредственно перед самим блоком. Что касается массивов, созданных с помощью функций из oleaut32.dll, то они используют IMalloc::Alloc и IMalloc::Free. Метод IMalloc::Free традиционно не принимает размер блока, а значит освободит именно тот блок, какой был выделен, ни байтом больше.

Другое дело, что функции SaMap и SaUnmap (а именно так я назвал функции в своих кирпичах, отвечающие за проецирование SAFEARRAY-массива на произвольный регион памяти) обычно принимают ссылку на массив ByRef. При этом они не знают, кто является владельцем массива (владелец отвечает за создание и уничтожение). Они не знают, чем пользовался владелец для создания и выделения. Поэтому они не могут со стопроцентной уверенностью полагаться на то, что для освобождения памяти будет использован метод IMalloc::Free.

С другой стороны, можно представить себе вилку вариантов: если SaMap принимает массив ByRef, то значит есть VB-шная переменная-массив. Значит либо массив был выделен самим VB, либо остаётся вариант, что массив сконструировала третья сторона (возможно, пользуясь нестандартным способом управления памятью) и записала указатель на SA-дескриптор в VB-шную переменную. Но стоит помнить, что во втором случае автоматическое удаление массива силами VB пойдёт по сценарию oleaut32.dll, то есть память будет освобождена с помощью IMalloc:Free вне зависимости от того, как она была выделена. Так что если VB-шную переменную-массив устанавливает третья сторона, то и зачистку она должна делать. И с такими массивами не нужно использовать трюки с подменой cElements.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot, Google-бот и гости: 46

    TopList