|
59 / 49 / 14
Регистрация: 23.02.2016
Сообщений: 433
|
||||||
Поэлементное выделение памяти30.07.2018, 20:12. Показов 2860. Ответов 11
Метки нет (Все метки)
Добрый вечер!
Многократно возникает следующая ситуация: допустим у нас есть цикл, в котором прописаны некоторые условия, попадая в которые мы получаем нужные нам числа, и перед нами стоит задача создать массив из этих чисел, чтобы дальше продолжить работу. Размер массива мы не знаем, так как не знаем сколько раз попадём в условия -- всё на рандоме, а потому нам приходится дублировать код. Как через оператор new выделять память на один элемент массива, писать туда элемент, при повторном прохождении добавлять памяти на следующий элемент и т.д. пока цикл не кончится? Мне представляется как-то так это всё дело int size = 1; int* array = new int[size], а потом в нужных местах писать что-то вроде new array[size++] для выделения памяти, но так память по моей логике не выделится... Векторами пользоваться нельзя. Типичный пример ситуации (часть кода после комментария /*Количество неповторяющихся элементов*/ приходится дублировать)
0
|
||||||
| 30.07.2018, 20:12 | |
|
Ответы с готовыми решениями:
11
Выделение памяти, проверка на утечку памяти Распределение памяти. Динамическое выделение памяти Выделение памяти |
|
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
|
||
| 30.07.2018, 20:37 | ||
|
2) Variable-length array массивы размер которых задается на стадии исполнения (но потом не меняется). Но его в стандарте C++ вообще нету (а компилятор скорее всего поддерживает). 3) Фиксированный массив размера "чтоб точно хватило". Но не экономно.
1
|
||
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|
| 30.07.2018, 21:10 | |
|
Можно объединить 1 и 3 варианты, предложенные мистером Renji:
• создать некий буффер ( массив фиксированного размера ), в который будут вноситься вводимые числа ; • создать указатель, который будет указывать на область памяти, где будут храниться все числа ( динамический массив ). В процессе ввода чисел, после того, как буффер заполняется ( кончается место в массиве ), мы берем и перевыделяем память в основном массиве ( область памяти, на которую ссылается тот самый указатель ) под такое кол-во элементов, чтобы скопировать прежние данные с основного массива + данные из буффера. Потом очищаем буффер, повторяем действия. Я известем своей отчетливостью ( нет ), потому если что-то не ясно — спрашивайте. Если все ясно — попытайтесь это реализовать сами. Если ничего не получится, тогда кину пример. Удачи.
2
|
|
|
7438 / 5030 / 2892
Регистрация: 18.12.2017
Сообщений: 15,692
|
||||||
| 30.07.2018, 21:46 | ||||||
|
Timurs, количество различных элементов можно находить проще, например так:
1
|
||||||
|
Злостный нарушитель
10311 / 5733 / 1269
Регистрация: 12.03.2015
Сообщений: 26,568
|
|
| 30.07.2018, 21:58 | |
|
А чо если для сохранения всех новых элементов использовать однонаправленный список, а после формирования - выделять память (1 раз) под массив для их хранения/обработки/сортировки и переносить данные из списка в этот массив с последующим освобождением памяти из-под элементов списка? Каждый элемент списка - это указатель на структуру, память под которую выделяется при добавлении указателя в конец списка, поэтому перераспределения и фрагментации не будет. Красота, ёмаё!
3
|
|
|
59 / 49 / 14
Регистрация: 23.02.2016
Сообщений: 433
|
||||||
| 31.07.2018, 01:32 [ТС] | ||||||
|
Renji, Captain Maxee, я Вас понял, но мне как раз и интересно как сэкономить память и не повторять проверки, то есть заведомо выделить память, чтоб точно на все элементы хватило ну вообще не вариант, неинтересно так. Просто мой мозг отказывается понимать почему куски памяти нельзя добавлять, такое чувство что можно, но что-то не так пишу.
Yetty, знаю, просто тут грубо говоря каждый элемент проверяется с каждым и мне показалось это совсем кривым вариантом, n^2 проверок, а через sort n*(n-1)/2 - 1 + этот for, в нём вроде бы 3n -- итого 0.5n^2+2.5n-1. не совсем понятно что именно Вам нужно. сформулируйте задачу Да всё просто, есть массив например 1, 2, 3, 4, 4 и я хочу 1, 2, 3 сразу писать в свежий массив походу дела, не выделяя заведомо память на три элемента. Но пишется только один элемент. А если раскомментить строки, то всё падает.
![]() Не понимаю... На векторе ж легко пушбэком в конец кидать, более того, я всегда и думал, что это именно так и реализовано. Verevkin, вот это походу то, что надо! Правда проблема есть одна -- не знаю что такое однонаправленный список и структура. Можете продемонстрировать как это прокрутить можно на примере кода что выше? Добавлено через 28 минут Точнее через сортировку вышло 0.5n*(n-1) + 2*(n-2) + 2 = 0.5n^2 + 2.5n + 2 проверки.
0
|
||||||
|
Злостный нарушитель
10311 / 5733 / 1269
Регистрация: 12.03.2015
Сообщений: 26,568
|
||||||||
| 31.07.2018, 08:25 | ||||||||
|
Вкратце: элементы списка представляют собой такую структуру:
![]() Мне работать надо, некогда мне. На форуме народу много и все шарят.
1
|
||||||||
|
Велосипедист...
353 / 220 / 73
Регистрация: 15.12.2015
Сообщений: 785
|
|||||||||
| 31.07.2018, 09:01 | |||||||||
Сообщение было отмечено Timurs как решение
Решение
| | — ячейка памяти ; * — какие-то данные.Вот, например, у тебя первые три звездочки ( * ) — массив int[ 3 ]. Дальше — две пустые ячейки памяти ( | | | ), а потом ( две звездочки ) — это какие-то другие данные... возможно, даже не относящиеся к твоей программе. Имеется в виду оперативная память, конечно же. А она, как известно, используется всеми запущенными приложениями, а не только тем, активное окно которого сейчас. И ты вот, вроде, сможешь добавить по 1 дополнительной ячейке два раза ( занять те две свободные ячейки памяти ( | | | ) ), а дальше что ? Дальше — занято. Придется перевыделить память в другом месте, где есть больше свободных ячеек. Потому вот и нельзя так просто.Теперь к делу... std::vector, то он в большинстве случаев, грубо говоря, реализован так, как я выше описал : если есть возможность занять несколько свободных ячеек «спереди», то он это и делает. Если нет — переносит массив в другое место, где есть больше ячеек для хранения информации. Естественно, вся эта реализация скрыта за методом push_back(), который, в свою очередь, скорее всего, внутри себя, вызывает другие методы. Но ты этого не видишь — в этом и вся прелесть ООП ( и функционального программирования в частности ).Чуть позже скину пример того, как можно решить твою задачу стандартными средствами.
0
|
|||||||||
|
Диссидент
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
|
|||||||
| 31.07.2018, 10:06 | |||||||
Сообщение было отмечено Timurs как решение
Решение![]() Вот в Си есть такая функция - realloc. Ее можно использовать и в плюсах, так как Си в обще-то подмножество С++. Но можно реализовать нужный тебе механизм и на new-delete. Суть в том, что выделяется новая область памяти, туда переписываются данные из старой, а старая уничтожается.
Но очень прошу тебя - никогда так не делай! Дело в том, что выделение памяти + копирование - все это достаточно дорого. И для каждой единицы все это проделывать - глупо. Поэтому умные люди выделяют память кусками. Собственно, приблизительно так и устроен vector. Добавлено через 9 минут Не по теме: Вот, навеяло... Добавлено через 1 минуту Не по теме: Точнее Добавлено через 1 минуту Там был переход через страницу и такой маленький глючок...
1
|
|||||||
|
7438 / 5030 / 2892
Регистрация: 18.12.2017
Сообщений: 15,692
|
|||||||
| 31.07.2018, 10:26 | |||||||
0
|
|||||||
|
475 / 427 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
|
|||||||
| 31.07.2018, 14:47 | |||||||
1
|
|||||||
|
59 / 49 / 14
Регистрация: 23.02.2016
Сообщений: 433
|
|||||||
| 04.08.2018, 18:42 [ТС] | |||||||
|
Байт, спасибо! Именно эта штука мне и интересна. Понял, так делать не буду, но для понимания как это работает разок-то надо сделать) Проблема в том, что всё равно не получается, хотя Ваш комментарий понял.
Добавлено через 25 минут
0
|
|||||||
| 04.08.2018, 18:42 | |
|
Помогаю со студенческими работами здесь
12
Выделение памяти
Выделение памяти Выделение памяти Выделение памяти Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Символьное дифференцирование
igorrr37 13.02.2026
/ *
Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2).
Унарный минус обозначается как !
*/
#include <iostream>
#include <stack>
#include <cctype>. . .
|
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
|
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу,
и светлой Луне.
В мире
покоя нет
и люди
не могут жить в тишине.
А жить им немного лет.
|
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила»
«Время-Деньги»
«Деньги -Пуля»
|
|
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога
Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
|
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога
Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
|
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
|