|
8 / 8 / 5
Регистрация: 28.10.2012
Сообщений: 135
|
||||||
Можно ли обойти динамический массив не зная его размер?11.04.2016, 02:13. Показов 15618. Ответов 79
Метки нет (Все метки)
1
|
||||||
| 11.04.2016, 02:13 | |
|
Ответы с готовыми решениями:
79
Можно ли создать массив, изначально не зная его размерности? Можно ли задать массив, не зная заранее его длину? |
|
Неэпический
|
|||
| 12.04.2016, 12:02 | |||
![]() См. стандарт, там об этом сказано!
0
|
|||
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
||
| 12.04.2016, 12:09 | ||
T* a;, где T* - тип переменой, а T - так называемый базовый тип. Тоесть в типе указателя уже есть тип объекта на который он ссылается. так ведь?
0
|
||
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 12.04.2016, 12:10 | ||
|
0
|
||
|
Неэпический
|
||||||
| 12.04.2016, 12:20 | ||||||
|
Опять же, по ссылке выше видно, что delete можно обмануть, правда при этом получим неопределенное поведение
А как там эти тапки реализованы - не важно, с точки зрения c++ разницы нет, важно лишь поведение. Добавлено через 2 минуты И виртуальность деструктора можно вывести из статического типа => решить как действовать можно на этапе компиляции. Никакой оверхед по памяти не нужен для этого. Добавлено через 2 минуты
3
|
||||||
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 12.04.2016, 12:32 | ||
|
Добавлено через 2 минуты для объектов размером больших 8 байт экономичнее по памяти пользовать заголовок с размером, чем побайтовую карту распределения.
0
|
||
|
Комп_Оратор)
|
|||||
| 12.04.2016, 14:04 | |||||
0
|
|||||
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
|||
| 12.04.2016, 14:56 | |||
|
Добавлено через 1 минуту
0
|
|||
|
Комп_Оратор)
|
|||
| 12.04.2016, 17:00 | |||
![]() Croessmah, я помню эту историю. Вообще, терминатор это весело если размер нужен для итерирования. А если он для другого нужен? Для копирования, например? Всё равно нужно пробежать до конца, чтобы размер узнать? Ты говоришь, - пойти в хвост и найти. Но это значит: 1. Нужно бежать до хвоста. Но если ты знаешь где, то зачем бежать? Значит не знаешь и бежишь "пока не хвост". То есть это история про хвост терминатор? ![]() 2. Если хвост, это хвост терминатор, то это значит что хвост должен как-то уж очень отличаться от не хвоста. А это как? Нежелание отвести место под размер массива в его начале, было продиктовано желанием сохранить обратную совместимость с С-массивами. Тут слово массивы в общем смысле. Ну а то, что для коротких целых типов не хватало места для записи в одном элементе и пришлось бы выделять, скажем 4-ре или более (от реализации) байт, это означало бы рост накладных расходов для очень коротких массивов. Для сохранения общности алгоритмов пришлось бы выделять несколько экземпляров места и для пользовательских типов, возможно. Может я не точно помню, но вроде такое, то-то читал.
0
|
|||
|
0 / 0 / 0
Регистрация: 12.04.2016
Сообщений: 9
|
||
| 12.04.2016, 17:18 | ||
![]() Если Вы не знаете, где конец, то машина и подавно.
0
|
||
|
8 / 8 / 5
Регистрация: 28.10.2012
Сообщений: 135
|
|
| 12.04.2016, 17:49 [ТС] | |
|
Да, понял что нельзя с помощью указателей!
Без всяких терминаторов.
0
|
|
|
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 12.04.2016, 18:09 | ||
|
0
|
||
|
Вездепух
13228 / 6860 / 1827
Регистрация: 18.10.2014
Сообщений: 17,385
|
||
| 12.04.2016, 19:00 | ||
Сообщение было отмечено IGPIGP как решение
Решениеdelete [] прочитает этот размер и вызовет правильное количество деструкторов.Но делается это только для массивов с нетривиальной деструкцией элементов. В общем же случае размер массива нигде не хранится. Все это, конечно же, детали реализации, но традиционные релизации работают именно так.
2
|
||
|
Комп_Оратор)
|
||
| 12.04.2016, 23:08 | ||
|
TheCalligrapher, спасибо, это очень интересно. Где об этом можно почитать?
Вот тут пока не могу себе представить:
0
|
||
|
8 / 8 / 5
Регистрация: 28.10.2012
Сообщений: 135
|
||
| 12.04.2016, 23:28 [ТС] | ||
Это...спасибо...
0
|
||
|
Вездепух
13228 / 6860 / 1827
Регистрация: 18.10.2014
Сообщений: 17,385
|
||||||||||||||||||||||
| 13.04.2016, 01:59 | ||||||||||||||||||||||
Сообщение было отмечено IGPIGP как решение
Решениеint нет деструкторов. По этой причине для таких типов вызов new[] превращается в тривиальный аналог malloc, а вызов delete[] превращается в тривиальный аналог free. Никаких конструкторов или деструкторов.Т.е. для типа int * delete [] вообще ничего не делает а сразу напрямую передает управление функции освобождения сырой памяти operator delete[](void *), которая изнутри себя фактически вызывает free.Так что вопрос сводится к тому, как free узнает, сколько памяти освободить. Очень просто узнает: malloc, когда выделял блок памяти, записал его размер куда-то (в начало блока обычно), а free просто извлекает этот размер оттуда же. Вот и все.-------------------- Таким образом, когда вы через new []/delete [] работаете с массивом, имеющим нетривиальный деструктор в типе элемента, то типичный выделенный блок памяти будет содержать целых два кусочка невидимой служебной информации: во-первых, это будет размер блока в байтах, записанный туда malloc (для free), во-вторых, это будет размер массива в элементах, записанный туда new[] (для delete []).
malloc (для free).
Например, вот такая простая программка покажет нам эти значения в GCC
new NonTrivial[29]:29 - это сохраненный new[] размер массива129 - это сохраненный malloc размер блока (с внутренними накрутками)Для new Trivial[29]:Размер массива не сохраняется вообще 121 - это сохраненный malloc размер блока (с внутренними накрутками)Для new int[29]:Размер массива не сохраняется вообще 121 - это сохраненный malloc размер блока (с внутренними накрутками)http://ideone.com/1weAK4
15
|
||||||||||||||||||||||
|
Комп_Оратор)
|
|
| 13.04.2016, 02:51 | |
|
TheCalligrapher, огромное спасибо! Вот за что наш форум, просто нельзя не любить. Такие вещи найти очень трудно.
TheCalligrapher, то есть компилятор всё же знает размер и для тривиальных и для не тривиальных блоков. Причём для нетривиальных пишется и размер в элементах, чтобы выравнивание не мешало. Но для встроенных типов выравнивание же не может быть? Это значит, что зная размер блока всегда можно точно и быстро посчитать размер в элементах? Почему же не реализована возможность определения длины? Конечно, ситуация острая в том смысле, что указатель может не указывать на начало и тогда прочтётся бог знает, что. Но пусть каждый отвечает за то что он делает. Зачем опекать? А как сохранить размер для массива short (2 bytes) если размер блока больше 65535 ? Для win32 размер индекса ограничивается максимумом для size_t (Uint32) то есть 4 294 967 295. В два байта не влезет же? ![]() Или размер служебной записи не равен длине элемента? Можно предположить что его и выбирают как длину типа для индексирования. Да?
1
|
|
|
Вездепух
13228 / 6860 / 1827
Регистрация: 18.10.2014
Сообщений: 17,385
|
|||||
| 13.04.2016, 03:48 | |||||
Сообщение было отмечено IGPIGP как решение
РешениеВыбор структуры блока на уровне new[]/delete[] (т.е. писать или не писать размер массива) - это действительно функциональность уровня компилятора, ибо решение принимается в зависимости от наличия у элементов массива нетривиального деструктора.Структура же блока на уровне malloc/free - это функциональность уровня библиотеки, о которой компилятор не знает и знать не может. Тут еще не следует забывать, что компилятор не вызывает напрямую именно malloc и free для выделения/освобождения сырой памяти. Компилятор вызывает функции operator new[] и operator delete[] для выделения/освобождения сырой памяти (а уж они, в умолчательном варианте, вызывают malloc и free или какие-то их аналоги). Пользователь имеет полное право заместить operator new[] и operator delete[] своим версиями и выделать память своими средствами со своим внутренним форматом хранения служебных данных об общем размере блока. Компилятор не хочет и не может ничего знать об этом внутреннем формате.Если вы сделаете new char[3] вы практически всегда можете быть уверенными, что фактически вам будет выделен блок памяти размером [намного] более 3 байтов.size_t и точка.
5
|
|||||
|
Вездепух
13228 / 6860 / 1827
Регистрация: 18.10.2014
Сообщений: 17,385
|
|||||||
| 03.03.2020, 04:43 | |||||||
|
В традиционных реализациях существует еще одна причина, которая должна заставлять реализацию new[] записывать в выделенный блок памяти точный размер массива (количество элементов). Одной причиной, уже упомянутой выше, является наличие в классе элемента нетривиального деструктора.Другая причина, которую я забыл упомянуть: наличие в классе перегруженного оператора вида
operator delete[], в котором присутствует второй параметр типа std::size_t. В такой ситуации компилятор обязан использовать этот оператор для освобождения массивов объектов данного класса и в качестве аргумента для второго параметра size передавать тот же самый размер, который передавался в operator new[] при выделении памяти для массива.Чтобы восстановить это значение точно, реализации нужно знать точный размер массива (количество элементов). Поэтому при появлении в классе такого перегруженного operator delete[] реализации обычно тоже тут же начинают сохранять точный размер массива в выделенном блоке памяти.См. обновленный пример: http://coliru.stacked-crooked.... b1aad47d57 При этом компилятор MSVC++ даже в версии 2019 содержит баг: он понимает, что при наличии в классе нетривального деструктора, следует сохранить в блоке памяти фактический размер массива, а вот наличие такого operator delete[] не приводит MSVC++ к тем же выводам. Сохранения размера массива не происходит и при вызове такого operator delete[] через второй параметр передается какое-то бессмысленное значение. Это является грубым нарушением требований языка.
4
|
|||||||
| 03.03.2020, 04:43 | |
|
Как правильно передать динамический массив в функцию, увеличивающую его размер, чтобы изменения сохранились
Создать массив с нулями и единицами в шахматном порядке, что бы его размер можно было вводить с клавиатуры
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
|
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#.
Название изменил на ColorStep.
Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
|
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами:
- ВидТО (СправочникСсылка. ВидыТО);
- ВидГСМ. . .
|
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала.
Ниже прикреплён. . .
|
|
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F
Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU.
Опрашиваются регистры. . .
|
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка:
Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
|
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо
Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
|
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман.
Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
|