Определить размер памяти, занимаемой массивом

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Определить размер памяти, занимаемой массивом

Сообщение Source » 11.09.2007 (Вт) 2:35

Dim Arr(9) as MyType

Private Type MyType
b as Byte
s as String
End Type

Как определить размер памяти, занимаемой Arr(9) c заполненным значениями элементов без перебора элементов и суммирования их длин (+ выравнивание по 4)?

Viper
Артефакт VBStreets
Артефакт VBStreets
Аватара пользователя
 
Сообщения: 4394
Зарегистрирован: 12.04.2005 (Вт) 17:50
Откуда: Н.Новгород

Сообщение Viper » 11.09.2007 (Вт) 7:04

Хотелось бы сказать элементарно, но есть нюанс. В общем случае размер занимаемой массивом памяти:
Код: Выделить всё
lenArray = (UBound(arr) - LBound(arr) + 1)*LenB(LBound(arr))

Если есть необходимость, то можно вспомнить о том, что массив есть структура SAFEARRAY и приплюсовать при необходимости ее размер (16 байт + 8 байт на каждую размерность). Однако, в сучае, когда в массиве находится структура состоящая из ссылочных типов (объекты, строки и так далее), то общая память будет больше, ибо LenB в данном случае посчитает только размер указателя (4 байта), а память на которую указывает этот указатель находится совсем в другом месте и подсчитывается отдельно.
Посему автору вопрос, какой размер памяти занимаемой массивом ему нужно знать и для каких целей?
Весь мир матрица, а мы в нем потоки байтов!

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 11.09.2007 (Вт) 14:22

надо размер данных в памяти, необходимо узнать средний размер заполненного данными элемента массива пользовательской структуры с переменными полями. Перебирать и суммировать поля не подходит, т.к. таких массивов множество и будет ещё множество.

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

Сообщение Хакер » 11.09.2007 (Вт) 14:44

Source
Средний размер элемента будет всегда одинаков - 5 байт.

Если требуется найти среднюю длину строки - то таки единственный вариант, суммировать длину всех строк и делить на кол-во.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 11.09.2007 (Вт) 18:00

ладно, размер элемента cbElements=5 байт, тогда как определяется размер данных элемента, тем более, если они сами структура?

Код: Выделить всё
Private Type SAFEARRAY
  cDims As Integer     'Число размерностей
  fFeatures As Integer 'Флаг, юзается функциями SafeArray
  cbElements As Long   'Размер одного элемента в байтах
  cLocks As Long       'Сколько раз массив был locked, но пока не unlocked.
  pvData As Long              'Указатель на данные.
  rgsabound As SAFEARRAYBOUND 'Повторяется для каждой размерности.
End Type

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

Сообщение Хакер » 11.09.2007 (Вт) 18:03

Какого ..кхм.. ты привёл сюда описание структуры SAFEARRAY ?
Ты вообще понимаешь, что ты делаешь?

И что есть "размер данных элемента"? Размер строки? Ты не знаешь как определить размер строки? Или не размер строки? А что тогда?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 11.09.2007 (Вт) 18:40

Хакер писал(а):Какого ..кхм.. ты привёл сюда описание структуры SAFEARRAY ?
Ты вообще понимаешь, что ты делаешь?

Чтобы было перед глазами и чтобы было удобно отвечать и спрашивать.

Хакер писал(а):И что есть "размер данных элемента"? Размер строки? Ты не знаешь как определить размер строки? Или не размер строки? А что тогда?


я хочу, чтобы на моём примере мне написали, как это всё выглядит в памяти, почему размер моей структуры 5 байт, д.б. 8, т.к. структура выравнивается по границе 4, что идёт далее в памяти по указателю pvData...

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

Сообщение Хакер » 11.09.2007 (Вт) 18:46

я хочу, чтобы на моём примере мне написали, как это всё выглядит в памяти


А может быть лучше самому снять дамп памяти и посмотреть?

почему размер моей структуры 5 байт, д.б. 8, т.к. структура выравнивается по границе 4

Почему 5 я думаю понятно?
Почему "д.б. 8" мне не понятно. Ничего не выравнивается.

что идёт далее в памяти по указателю pvData

Первый элемент массива.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 11.09.2007 (Вт) 19:15

А может быть лучше самому снять дамп памяти и посмотреть?


Ты всегда снимаешь дамп памяти, чтобы посмотреть неизвестную тебе структуру? Наверное, в дампе памяти написано Этот Long указатель на указатель, а этот Long - флаги и т.д. :)

Почему 5 я думаю понятно?
Почему "д.б. 8" мне не понятно. Ничего не выравнивается.


5 - размер полей структуры, 4 - размер строки (типа указатель на строку), так почему указателем не считать b as Byte, в конце коцов поле b as Byte занимает 4 байта, т.к. структура выравнивается в памяти по границе 4
что идёт далее в памяти по указателю pvData
Первый элемент массива.

Сразу данные, или есть некая шапочка - описание структуры элементаХакер, если тебе не хочется отвечать, не отвечай, придираться ко мне не надо. Мне надо описание структуры данных в памяти для массива Arr(0 to 1) as MyType, если кому не лень, напишите плиз, от начала структуры до последнего байта данных массива в памяти.
Последний раз редактировалось Source 11.09.2007 (Вт) 19:22, всего редактировалось 1 раз.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.09.2007 (Вт) 19:16

Хакер писал(а):
почему размер моей структуры 5 байт, д.б. 8, т.к. структура выравнивается по границе 4

Почему 5 я думаю понятно?
Почему "д.б. 8" мне не понятно. Ничего не выравнивается.

Выравнивается.
Проверь и узри.
Изображение

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

Сообщение Хакер » 11.09.2007 (Вт) 19:17

.....
SAFEARRAY
Баунды
.....
BYTE
DWORD
BYTE
DWORD
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение Хакер » 11.09.2007 (Вт) 19:20

tyomitch
Код: Выделить всё
Private Type t_5bytes
    spacer(1 To 5) As Byte
End Type
Private Sub Form_Load()
    Dim ega(10) As t_5bytes
    Debug.Print VarPtr(ega(5)) - VarPtr(ega(4))
End Sub


Проверка показала, что пятибайтовый элемент не выравнивается по двордной границе.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.09.2007 (Вт) 19:22

Автору: массив, содержащий строки, хранится в многих независимых местах.
Отдельно SAFEARRAY, отдельно сами данные (их 8*число_элементов байт), отдельно (от вышеназванного и друг от друга) строки.
Изображение

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.09.2007 (Вт) 19:26

Хакер, ты не выдумывай свой массив, а возьми тот массив, что у автора.
Изображение

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

Сообщение Хакер » 11.09.2007 (Вт) 19:28

tyomitch
Ты перепутал. Не массив, а тип.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 11.09.2007 (Вт) 19:36

SAFEARRAY
Баунды
.....
BYTE
DWORD
BYTE
DWORD


BYTE данных? А где указание массиву, что структура элемента - BYTE, DWORD? DWORD - указатель на строку? А где указание массиву, что DWORD - указатель на строку, а не на другой массив и что это вообще указатель, а не Long данных?
Последний раз редактировалось Source 11.09.2007 (Вт) 19:47, всего редактировалось 1 раз.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 11.09.2007 (Вт) 19:40

Хакер, у тебя другой массив, чем у автора. Возьми тот массив, что у автора, и поэкспериментируй с ним.

Source, приватному массиву нет указания на то, что структура элемента - BYTE, BYTE padding[3], BSTR. Зачем оно ему?
Изображение

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

Сообщение Хакер » 11.09.2007 (Вт) 19:40

Source
В этих "указаниях" нет нужды. Ну и я таки ошибся, там ещё триплеты нулевые между байт-дворд-ами.

Ну, если рассуждать по твоему - то кому по твоему эти указания нужны?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 11.09.2007 (Вт) 19:53

Я что-то совсем запутался. Хотел написать ф-ю, которой передаётся указатель на массив и по внутреннему описанию массива в памяти ф-я шагает по памяти и собирает размеры данных - можно всего массива, можно для 1 элемента - практично для As UserType. Да и в конце концов, неужели такого ещё нет?
P.S. Что-то у меня этот сайт сильно тормозит, господа, переходите сюда http://forum.sources.ru/

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

Сообщение Хакер » 11.09.2007 (Вт) 20:03

P.S. Что-то у меня этот сайт сильно тормозит, господа, переходите сюда http://forum.sources.ru/


1) http://bbs.vbstreets.ru/viewtopic.php?t=32459
2) Приходит на один проект, и открыто говорить "Переходите на другой!" - высший пилотаж наглости.

Хотел написать ф-ю, которой передаётся указатель на массив и по внутреннему описанию массива в памяти ф-я шагает по памяти и собирает размеры данных - можно всего массива, можно для 1 элемента - практично для As UserType.


Ты хотел для любого UDT это сделать что-ли? Так оно так нельзя. Лишь для некоторых, у которых есть описывающий ITypeInfo.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.09.2007 (Ср) 8:23

Флейм отделён в Холиворы.
Изображение

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 12.09.2007 (Ср) 16:03

Итак, продолжим наш незатейливый разговор. Значит, DWORD, как я понял, указатель на строку, раз никто не говорит обратного. Известно, что первый DWORD лежит в памяти по смещению 1 от pvData. Или же всё таки по смещению 4. Задача - получить указатель, зная смещение от начала структуры данных элемента (VarPtr(Arr(0)+4)), по этому указателю получить размер строки. Как?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.09.2007 (Ср) 16:21

Всё-таки по смещению 4.

Размер строки хранится непосредственно перед ней.

Но только зачем тебе весь этот экстрим? Len(Arr(0).s) мало?
Изображение

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 12.09.2007 (Ср) 16:57

затем, что мне будет известно только смещение в структуре, по смещениям я переберу все строки и получу их длины, всё и было задумано, чтобы явно не писать Arr(0).s. Вообщем, как по указателю получить значение ячейки памяти?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 12.09.2007 (Ср) 17:27

Например, можешь объявить себе функцию Peek.
Изображение

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 12.09.2007 (Ср) 18:33

Интересно, зачем в VB есть ф-и получения указателей, если даже нет ф-й по получению значений в памяти по указателю?
Как я понимаю, неявный перебор элементов структуры с целью определения их типа невозможен?

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 12.09.2007 (Ср) 19:06

вот код, который у меня получился, надеюсь, верный:
Код: Выделить всё
Private Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long

Private Type stru
    b As Byte
    s As String
End Type

Private Sub Form_Load()

Dim Arr(9) As stru, d As Long, res As Long, LenStr As Long
    Arr(0).s = "aaa"   
    res = GetMem4(VarPtr(Arr(0)) + 4, VarPtr(d))
Debug.Print d; StrPtr(Arr(0).s)
    res = GetMem4(d - 4, VarPtr(LenStr))
Debug.Print LenStr / 2; Len(Arr(0).s)

End Sub

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 12.09.2007 (Ср) 22:06

да тут не всё так просто, как кажется! Оказывается, Byte не выравнивается, Boolean и Integer выравниваются по границе 2, String выравниваtтся по границе 4. Остальные типы не проверял. Странно...
Код: Выделить всё
Private Type stru
    name1 As Byte
    name2 As Byte
    name3 As Byte   
    name4 As Integer   
    name5 As Byte   
    name6 As String
End Type

Private Sub Form_Load()
Dim Arr(9) As stru
Debug.Print "name1 As Byte"; VarPtr(Arr(0).name1) - VarPtr(Arr(0))
Debug.Print "name2 As Byte"; VarPtr(Arr(0).name2) - VarPtr(Arr(0))
Debug.Print "name3 As Byte"; VarPtr(Arr(0).name3) - VarPtr(Arr(0))
Debug.Print "name4 As Integer"; VarPtr(Arr(0).name4) - VarPtr(Arr(0))
Debug.Print "name5 As Byte"; VarPtr(Arr(0).name5) - VarPtr(Arr(0))
Debug.Print "name6 As String"; VarPtr(Arr(0).name6) - VarPtr(Arr(0))
Unload Me
End Sub
Последний раз редактировалось Source 13.09.2007 (Чт) 3:34, всего редактировалось 1 раз.

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 13.09.2007 (Чт) 3:32

а отсюда вывод - меньше всего места занимает в памяти структура, элементы которой сгруппированы по типу данных.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 13.09.2007 (Чт) 3:54

Source писал(а):Интересно, зачем в VB есть ф-и получения указателей, если даже нет ф-й по получению значений в памяти по указателю?

Для вызовов API.

Source писал(а):Как я понимаю, неявный перебор элементов структуры с целью определения их типа невозможен?

Невозможен. А зачем это? В отладочных целях? Для статистики?

То, что каждый тип выравнивается на собственный размер, но не крупнее 4 байт, имеет глубинный архитектурный смысл. На эту тему у ANDLL была иллюстрированная статейка.
Изображение


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

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

Сейчас этот форум просматривают: Majestic-12 [Bot], SemrushBot, Yandex-бот и гости: 86

    TopList