|
8 / 8 / 5
Регистрация: 28.10.2012
Сообщений: 135
|
||||||
Можно ли обойти динамический массив не зная его размер?11.04.2016, 02:13. Показов 14833. Ответов 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 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 12.04.2016, 12:10 | ||
|
0
|
||
|
Неэпический
|
||||||
| 12.04.2016, 12:20 | ||||||
|
Опять же, по ссылке выше видно, что delete можно обмануть, правда при этом получим неопределенное поведение
А как там эти тапки реализованы - не важно, с точки зрения c++ разницы нет, важно лишь поведение. Добавлено через 2 минуты И виртуальность деструктора можно вывести из статического типа => решить как действовать можно на этапе компиляции. Никакой оверхед по памяти не нужен для этого. Добавлено через 2 минуты
3
|
||||||
|
2083 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 12.04.2016, 12:32 | ||
|
Добавлено через 2 минуты для объектов размером больших 8 байт экономичнее по памяти пользовать заголовок с размером, чем побайтовую карту распределения.
0
|
||
|
Комп_Оратор)
|
|||||
| 12.04.2016, 14:04 | |||||
0
|
|||||
|
2083 / 1575 / 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 / 1575 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
|
||
| 12.04.2016, 18:09 | ||
|
0
|
||
|
Вездепух
13205 / 6840 / 1822
Регистрация: 18.10.2014
Сообщений: 17,298
|
||
| 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
|
||
|
Вездепух
13205 / 6840 / 1822
Регистрация: 18.10.2014
Сообщений: 17,298
|
||||||||||||||||||||||
| 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
|
|
|
Вездепух
13205 / 6840 / 1822
Регистрация: 18.10.2014
Сообщений: 17,298
|
|||||
| 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
|
|||||
|
Вездепух
13205 / 6840 / 1822
Регистрация: 18.10.2014
Сообщений: 17,298
|
|||||||
| 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 | |
|
Помогаю со студенческими работами здесь
80
Как правильно передать динамический массив в функцию, увеличивающую его размер, чтобы изменения сохранились
Создать массив с нулями и единицами в шахматном порядке, что бы его размер можно было вводить с клавиатуры
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
| Опции темы | |
|
|
Новые блоги и статьи
|
|||
|
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта
Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
|
попытка написать игровой сервер на C++
pyirrlicht 29.04.2026
попытка написать игровой сервер на плюсах с открытым бесконечным миром.
возможно получится прикрутить интерпретатор питон для кастомизации игровой логики.
что есть на текущий момент:. . .
|
Контроль уникальности выбранного документа-основания при изменении реквизита
Maks 28.04.2026
Алгоритм из решения ниже разработан на примере нетипового документа "ЗаявкаНаРемонтСпецтехники", разработанного в КА2.
Задача: уведомлять пользователя, если указанная заявка (документ-основание). . .
|
Благородство как наказание
Maks 24.04.2026
У хорошего человека отношения с женщинами всегда складываются трудно. А я человек хороший. Заявляю без тени смущения, потому что гордиться тут нечем. От хорошего человека ждут соответствующего. . .
|
|
Валидация и контроль данных табличной части документа перед записью
Maks 22.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в КА2.
Задача: контроль и валидация данных табличной части документа перед записью с учетом регламента компании. . .
|
Отчёт о затраченных материалах за определенный период с макетом печатной формы
Maks 21.04.2026
Отчёт из решения ниже размещён в конфигурации КА2.
Задача: разработка отчёта по затраченным материалам за определённый период, с возможностью вывода печатной формы отчёта с шапкой и подвалом.
В. . .
|
Отчёт о спецтехнике находящейся в ремонте
Maks 20.04.2026
Отчёт из решения ниже размещен в конфигурации КА2.
Задача: отобразить спецтехнику, которая на данный момент находится в ремонте.
Есть нетиповой документ "Заявка на ремонт спецтехники" который. . .
|
Памятка для бота и "визитка" для читателей "Semantic Universe Layer (Слой семантической вселенной)"
Hrethgir 19.04.2026
Сгенерировано для краткого описания по случаю сборки и компиляции скелета серверного приложения. И пусть после этого скажут, что статьи сгенерированные AI - туфта и не интересно. И это не реклама -. . .
|