Перейти к содержимому

Сколько байт занимает массив

  • автор:

Сколько выделяется памяти под массив в C++?

то сколько выделится памяти под массив? Зависит от компилятора?
Я предполагаю, что выделится ровно столько, сколько элементов перечислено в списке (т. е. sizeof(тип) * количество элементов в списке).

  • Вопрос задан более трёх лет назад
  • 3537 просмотров

Комментировать
Решения вопроса 2

Я предполагаю, что выделится ровно столько, сколько элементов перечислено в списке

Совершенно верно за одним исключением. Памяти может выделятся чуть больше из-за выравнивания. Доступ к памяти по выровненным адресам намного быстрее происходит, из-за чего эффективнее например выделить дополнительный байт в начале (что бы адрес массива стал кратным 2/4/8/16 (смотря какое выравнивание в архитектуре используется).

Ответ написан более трёх лет назад
Нравится 3 9 комментариев
DVoropaev @DVoropaev Автор вопроса
а можно ли как-то узнать, сколько байтов выделяется дополнительно?

dableproger: возможно попробовать перед массивом объявить переменную и вычислить разность адреса массива и адреса переменной и ещё отнять размер переменной. Получите размер неиспользуемого места перед массивом.

Вот только я не уверен, гарантирует ли компилятор определённый порядок переменных. В структурах гарантирует точно.

SolidMinus @SolidMinus

fshp: гарантирует. В обеих случаях. И на стеке и на куче.

Вот только в случае со стеком — они будут в обратном порядке. Стек растет в сторону уменьшения адресов, то есть более «поздняя» переменная выделится в стеке «выше», т.е по адресам она будет раньше.

Связано это с тем, что локальные переменные на стеке выделяются через вычитание требуемой памяти из указателя на вершину стека, и добавление инициализированных переменных через push до этого, которая кладет их «сверху» стека.

SolidMinus: на куче точно не гарантирует, т.к. память может быть фрагментирована. И если первое выделение не помещается в первый фрагмент, а второе помещается — то адреса будут в обратном порядке.

А со стеком верное замечание, да.

SolidMinus @SolidMinus
fshp: хм, про фрагментацию забыл. Вы правы.

SolidMinus: При оптимизации ничего не гарантируется вообще. Может поменять местами переменные: coliru.stacked-crooked.com/a/e15e0295e1036c37

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

SolidMinus @SolidMinus

MiiNiPaa: переменные на которые есть reference в коде удалить он не может, он может их оптимизировать в использование регистрами, в примере он их удалил потому что дабл нигде не используется, але)))

Но если в коде будет оператор & перед именем переменной — в регистр он ее не запихнет, т.к у регистров нет адреса в памяти.

Изменение порядка такое связано с тем, что double занимает памяти больше чем int, поэтому сначала пушится инт, потом дабл. Имелось ввиду переменные одного типа.

Ты лучше не адреса выводи через принтф, а дизассемблируй мейн функцию и смотри как что меняется там.

Сколько байт занимает число в массиве int?

1.Зависит ли размерность int от того, какое число туда записано, или оно все время будет занимать 4 байта?
2.Если у нас есть 20 байтовый ключ 0x707172737475767778797a7b7c7d7e7f80818283, то массив данных из 20 байт будет выглядеть так? :
array[5] = ?
Или можно разбивать как нибудь по другому?
Спасибо.

Голосование за лучший ответ

1. любая переменная типа int 4 байта, даже если ее просто создать и ничего туда не записать, все равно 4 байта.

1. Размер постоянный, но 4 ли байта — зависит от кучи факторов, начиная с языка (ты не думал, что тип int есть в разных языках?).
2. Это существенно зависит от языка и архитектуры компьютера. В большинстве систем используется порядок байт от младшего к старшему (англ. little-endian), поэтому начало массива будет выглядеть как
0x73, 0x72, 0x71, 0x70, 0x77, ..
А вообще разбивать можно как угодно, главное, договориться, как именно, и собирать в том же порядке.

Ilja ***Ученик (88) 8 лет назад
т. е. если я представляю 64 байтное сообщение как int array[64] — это неверно?

Капитан Гугл Искусственный Интеллект (146171) Это неудобно, но таким можно будет пользоваться. А вообще прочитай мой ответ еще раз и учти, что я не телепат.

Если вы объявите ключ как byte key[20], будет гораздо понятнее.
Ilja ***Ученик (88) 8 лет назад

дело в том, что с этим ключом произвожу манипуляции (подстановка, перестановка). и там числа большие и влазят в Byte. вот пытаюсь свести как то к int

The Cat Искусственный Интеллект (116063) Вы всё равно работаете с отдельными битами ключа. (Так ведь? Иначе. :))

1 памяти под integer 4 байта выделяется.
2 эт хз

Если будут байты, то нафига интеджер объявлять? Но на крайняк, есть так называемые упакованные массивы (packed arreys). Правда не все языки его потдерживают, к тому же они время процессорное жрут как свиньи.

Типа int? Всегда, это будет 4 байта.

Есть число 15 это 15, а интегер 32 тыщи может вместить число. А 4 байта просто выделяются в оперативке.

Форум MATLAB и Simulink

https://hub.exponenta.ru/

Пожалуйста, подскажите функцию, с помощью которой можно определить объем памяти занимаемый массивом — никак не могу найти.

nparfenukoff Эксперт Сообщения: 399 Зарегистрирован: Сб июн 25, 2005 10:43 am

Сообщение nparfenukoff » Ср янв 31, 2007 1:03 am

Созданный по умолчанию массив имеет тип double (двойная точность) для каждого элемента. Привести его к типу single (одинарная точность) можно функцией single:
b = single(a) или наоборот
a = double(b)
Элемент типа double занимает в памяти машины 8 байт, тогда как single 4 байта.
Поэтому, размер массива в байтах можно узнать так:

8 1 6
3 5 7
4 9 2

затем домножить на 8, в случае, если Вы с массивом до этого ничего не делали, на 4 в случае, если Вы его усекали до типа single или на размер элемета того типа, к которому Вы его привели в общем случае.
Проверить правильность Ваших вычислений можно так:

>> whos a
Name Size Bytes Class

a 3×3 72 double array

Grand total is 9 elements using 72 bytes

Сколько занимает элемент массива в памяти?

Объясните мне пожалуйста одну простую вещь. long unsigned int = 4 байта.
1024 * 1024 * long unsigned int = 4 мегабайта. Почему же массив, наполненный числами от 0 до 1024 * 1024 занимает в памяти 40 мегабайт? (в php еще в два раза больше). Я понимаю, у каждого элемента есть там индекс, указатели какие-то, но хочу не понимать, а четко знать, куда моя память тратится? По просьбе трудящихся прикладываю код:

var i = 1024 * 1024, arr = []; while(i--) arr.push(i); 

По просьбе трудящихся прикладываю скрины: Win 7:
введите сюда описание изображения Win 8:
введите сюда описание изображения Ubuntu (как это интерпретировать я хз, но кому интересно вот): введите сюда описание изображения P.S. Из чего вообще возник этот вопрос — у меня есть около 3кк ip адресов, которым надо в соответствие поставить 3кк неких id. Но на это уходит почти гигабайт этой самой памяти (два массива по три миллиона чисел или объект с ключом-значением, разница небольшая), тогда как csv-файлик со двумя столбцами этих чисел весит всего 30мб.

Отслеживать
задан 10 мар 2016 в 11:52
13.1k 2 2 золотых знака 25 25 серебряных знаков 56 56 бронзовых знаков

Хотите четко знать — посмотрите исходники движков js и php. Организация памяти из внутреннее дело и может меняться от версии к версии конкретного продукта. Если даже сейчас это посмотреть и написать тут ответ, то завтра ситуация может в корне изменится

10 мар 2016 в 11:57
Комментарии не предназначены для расширенной дискуссии; разговор перемещен в чат.
– user177221
17 мар 2016 в 11:22

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

Для начала, не стоит в языках со сборкой мусора пытаться что-либо связанное с внутренним устройством памяти замерить снаружи. RSS — объем ОП, который занимает сам процесс ноды, с тем, сколько реально «занято», а сколько «прозапас» коррелирует слабо.

В частности, нода, очень любит кушать память. Пока система дает ей оперативную память, она будет ее запрашивать, если происходит много аллокаций. Сделано это прежде всего для скорости работы.

Как верно заметил Artur Udod в комментарии, в javascript, согласно стандарту, все числа — 64х битовые, т.е. 8 байт на число.

Чтобы замерить правильно размер 1 элемента массива — необходимо снимать хипдамп, искать там нужный объект и смотреть, а сколько же реально места там занято.

Есть вариант грубого замера. Для этого — запускаем node —expose-gc . Данный флаг позволяет принудительно инициировать отчистку мусора.

Посредством нехитрых вычислений вида:

var a = []; var memBefore = 0; var memAfter = 0; var length = 1000000; gc(); memBefore = process.memoryUsage().heapUsed; (function(len) < for(var i = 0; i < len; i++)< a[i] = i; >>)(length); gc(); memAfter = process.memoryUsage().heapUsed; console.log('Memory used by 1 element is:', (memAfter - memBefore) / length); 

Получим примерный размер элемента массива в памяти. Тут следует учитывать, что будет погрешность в большую сторону, т.к. REPL на разбор запросов тоже будет кушать память. Причем из той же кучи.

Замерил хип дампом, через аллокацию массива с 100к элементов:

Скриншот хипдампа

Здесь — 8,53 байта на элемент массива. Однако, стоит помнить, что сам массив тоже занимает память.

В целом, Mike верно подметил, внутреннее устройство, действительно сильно зависит от версии движка, с этим ничего не поделаешь.

Еще один забавный момент заключается в том, что внутреннее устройство массива в V8 сильно зависит от его размера и структуры. К примеру в node версии 5.7.1 массив на 810 312 элементов «весит» значительно больше (примерно 12 байт на элемент), чем на 810 311 элементов (8,004 байта), это уже привет внутреннему устройству движка, вполне возможно, что он просто превращает массив в словарь, тут уже гадать не буду, однако с дальнейшим ростом, «размер» элемента массива опять падает.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *