Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76

Беда с resize() для vector<uint8_t>

19.02.2025, 14:33. Показов 3777. Ответов 20

Студворк — интернет-сервис помощи студентам
В коде использую несколько векторов. В описании класса перечисляю указатели на них так:

C++
1
2
3
vector<bool>           *pLedStates = nullptr;
vector<Color_struct>   *pLedColors = nullptr;
vector<uint8_t>        *pNZR       = nullptr;
В конструкторе создаю для них собственно векторы:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
WS2812B::WS2812B (uint16_t LedStripSize, PeriphTypeEnum PeriphType, uint8_t PeriphNumber, PinRemapEnum PinRemap, BlinkStatusEnum BlinkStatus, uint8_t BlinkTIMERx):
 
  pWS2812B            (this),
  NumberOfLeds        (LedStripSize),
  NumberOfReset       ((LedStripSize<4) ? 0 : (LedStripSize%3) ? (LedStripSize/3) : (LedStripSize/3 - 1)), 
  PeriphAddr           (0),
  DmaAddr              (0),
  DmaCh                (0),
  NzrArrSize           (0),
  NumberBytesForOneLed (0),
  NumberBytesForReset  (0),
 
  //---ВОТ ОНИ !!!-------------------------------------------------------------//
  pLedStates           (new vector<bool>(LedStripSize)),
  pLedColors           (new vector<Color_struct>(LedStripSize)),
  pNZR                 (new vector<uint8_t>),
  //------------------------------------------------------------------------------//
  LedMask              (0)
{
;
//...//
}
В коде программы для векторов делаю resize(). В частности для pNZR делаю это дважды. После первого pNZR->resize(119) в отладке наблюдаю такое:

По адресу __begin_ 0x20000248 будет лежат первый элемент вектора. Далее заполняю вектор, в памяти смотрю данные и всё там ОК: первый элемент лежит по адресу 0x20000248. Работаю с данными - всё замечательно.

Затем мне снова надо сделать pNZR->resize(131), было 119 элементов, а хочу 131:

По адресу __begin_ 0x00000000 как бы должен лежать первый элемент, но адрес не должОн быть таким. Далее в коде при заполнении вектора первый элемент по этому адресу, конечно, отсутствует и код, соответственно, шлёт меня подальше.

ЧТО Я ДЕЛАЮ НЕПРАВИЛЬНО?

P.S.:
С другими векторами делаю подобное, но такого не происходит, resize() делается как положено. Делал также несколько раз - всё работает.
Пробовал для pNZR делать перед вторым resize() вот так: pNZR->capacity(). Возвращалось значение 119.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
19.02.2025, 14:33
Ответы с готовыми решениями:

Для чего в данном коде vector.resize()
for(size_t i = 0; i &lt; row; ++i) { imatrix.resize(col); for(size_t j = 0; j &lt; col; ++j) imatrix =...

resize и vector
что делает функция resize в vector? ну например ...... ...... vector&lt;int&gt;tin; ..... ..... tin.resize(n);?

Vector::resize
Можно ли где-то найти код этой функции?

20
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
19.02.2025, 14:53
Вектор хранит все свои элементы в памяти непрерывно. Если при ресайзе места под новые элементы не хватает, он реаллоцирует их в другое место. Соответственно, надо обновить указатель на первый элемент при каждом ресайзе. Иначе могут происходить внезапные падения приложения, что у вас, похоже, и наблюдается. Другим решением проблемы, наверное, может служить резервирование под вектор максимально возможного (адекватного) числа элементов, если оно известно заранее, но такое решение попахивает костылем и генератором ошибок. Уж лучше тогда использовать обычный массив.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
19.02.2025, 15:01
1. Не понятно зачем вы объявляете указатель на вектор, после чего вектор конструируете через new.
У меня есть лишь одно предположение: ранее вы работали с массивами через указатель, теперь решили использовать STL, но немного не разобрались в каком месте динамичность размера вектора возникает.

В общем сделайте просто:

C++
1
2
3
vector<bool>           LedStates;
vector<Color_struct>   LedColors;
vector<uint8_t>        NZR;
и уберите из кода все эти new для векторов. Обращение к методам вектора, конечно, замените с -> на точку.
2
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 15:01  [ТС]
Цитата Сообщение от Anvis Посмотреть сообщение
надо обновить указатель на первый элемент
Как это сделать?

Вообще я знаю, что адрес первого элемента изменится после resize(), поэтому обращаюсь к нему через указатель на сам вектор.
К элементам вектора так:
pNZR->at(i);
Если нужен указатель на первый элемент, то так:
pNZR->data();

А как обновить указатель на первый элемент?
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
19.02.2025, 15:07
Так указатель на вектор и не изменится. Не знаю пока, проблема скорее всего в pNZR->data(), но нужно смотреть сам код. Для начала возьмите первый элемент как pNZR->at(0) и подумайте, может объявление вектора через new действительно лишее.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
19.02.2025, 15:10
2.
Цитата Сообщение от Alexey9891 Посмотреть сообщение
По адресу __begin_ 0x00000000 как бы должен лежать первый элемент, но адрес не должОн быть таким.
Судя по названию переменных предполагаю, что это у вас Embeded (вектор из разноцветных светодиодиков как бы намекает).
Зачем в Embeded работа с динамической памятью - вопрос несколько риторический, ну да ладно, например у нас программно конфигурируемая длина ленты.

Так вот в микроконтроллере нулевой адрес в памяти данных - абсолютно валидный адрес. Собственно почему он должен быть невалидным? адреса начинаются с нуля.
Просто так сложилось, что на привычной платформе x86 адреса вокруг нулевого (снизу памяти и "сверху") искусственно объявлены "недопустимыми". Хотя нулевой адрес ячейки памяти в микросхеме ничем не хуже любого другого адреса ячейки памяти.

Цитата Сообщение от Anvis Посмотреть сообщение
проблема скорее всего в pNZR->data(),
Нет там проблемы.

Не по теме:

Долой дискриминацию нулевых адресов!
Там явно от нас что-то скрывают, искусственно ограничивая доступ!!
Это заговор мирового закулисья! ячейки памяти по нулевым адресам делают, деньги за них берут(!!), но читать / писать туда не дают. Ради наживы впаривают! или явно что-то скрывает от нас Билл Гейтс по секретному договору с тайваньскими компаниями. наверняка ДНК новых короновирусов скрывают, не зря же он так быстро по всему миру распространяется - потому что ДНК уже вшит в нулевые адреса памяти незаметно!
Нипазволим-нипрастим! Совсем за дураков нас держат!



Добавлено через 2 минуты
Цитата Сообщение от Alexey9891 Посмотреть сообщение
Как это сделать?
Не надо этого делать.
Я по заголовку тоже подумал, что вы сохраняете адрес элементов вектора, но этого в коде нет, так что всё нормально.
(ну за исключением того, что нет смысла создавать вектор через new)
0
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 15:14  [ТС]
Цитата Сообщение от KSergey9 Посмотреть сообщение
уберите из кода все эти new для векторов
Это я вот ТУТ нахватался.
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
19.02.2025, 15:22
Ну таки да, элемены формы обычно хранят в куче. А у вас - вектор с какими-то данными. Это я когда-то давно тоже такого "нахватался" и навыделял под каждый пиксель new QColor(). Потому что: "ну а чо, так же прикольнее!" И (поскольку за неправильное освобождение памяти никто мне по голове не стучал) потом с интересом наблюдал адовую утечку памяти после каждого обновления виджета

К слову, недавно я действительно использовал указатель на контейнер. Так было надо, чтобы избавиться от кучи if. Но я брал его через ссылку, при этом четко понимал его время жизни и при работе с указателем не вносил в сам контейнер никаких изменений.
0
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 15:38  [ТС]
Цитата Сообщение от KSergey9 Посмотреть сообщение
ранее вы работали с массивами через указатель
А работать с векторами через указатель не принято? Как тогда передавать вектор-параметр в функцию?

Добавлено через 6 минут
Цитата Сообщение от KSergey9 Посмотреть сообщение
и уберите из кода все эти new для векторов
Идея была такая. В описании класса я ещё не знаю сколько диодов, поэтому храню там только указатель на вектор связанный с этим количеством. Когда пользователь вызовет конструктор, он в вызове укажет количество светодиодов, и я в конструкторе создам вектор через new под необходимое количество диодов.
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
19.02.2025, 15:38
В подавляющем большинстве случаев -
foo(const vector<... > &v)
Или без const, если хотите менять его в функции.
Или объявить функцию как
foo(vector<double> *v), объявлять и передавать в нее вектор, например, вот так:
C++
1
2
vector<double> v;
foo(&v);
Но обычно используют все же передачу по ссылке.

Upd:
Для случаев, когда заранее не известен размер массива, как раз и существует вектор. Идея, которую вы описали, больше подходит для более низкоуровневого управления памятью, через обычные динамические массивы, а вектор как раз позволил бы написать это все компактнее. Если вам позволяют пользоваться вектором - используйте его и объявляйте в стеке.

Ладно, отпускай меня работать. А то на меня уже начальник криво косится
0
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 15:40  [ТС]
Цитата Сообщение от KSergey9 Посмотреть сообщение
В общем сделайте просто:
C++Скопировано
1
2
3
vector<bool>           LedStates;
vector<Color_struct>   LedColors;
vector<uint8_t>        NZR;
Я так понял Вы предлагаете в описании класса (в .h - файле) объявить векторы без указания количества элементов, а потом когда это количество станет известным делать каждому resize(). Так?
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
19.02.2025, 15:50
Цитата Сообщение от Alexey9891 Посмотреть сообщение
Как тогда передавать вектор-параметр в функцию?
Через ссылку

Добавлено через 2 минуты
Цитата Сообщение от Alexey9891 Посмотреть сообщение
А работать с векторами через указатель не принято?
А смысл?
Дополнительно занимать память под указатель на вектор плюс дополнительно занимать память менеджера кучи плюс вызов менеджера кучи для создания экземпляра вектора, а потом тоже самое для удаления через delete - чтобы что?
Сплошной оверхед и по памяти, и по производительности, а смысл мне не ясен (в вашем случае)

PS
Зачем такая парадигма принята в QT - не ведаю, не сталкивался никогда.
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
19.02.2025, 15:51
Можно вообще не делать resize. Просто добавляйте элементы через push_back и на всякий случай прочитайте, что такое reserve
0
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 15:51  [ТС]
Цитата Сообщение от Anvis Посмотреть сообщение
Тот случай, который вы описали
Задача состоит не в том, чтобы подобрать для этого случая идеальное решение (использование обычных динамических массивов, разработка на С/ассемблере/перфокартах), а в том, чтобы правильно заработало с векторами.
0
631 / 526 / 104
Регистрация: 05.08.2022
Сообщений: 2,810
19.02.2025, 15:52
Цитата Сообщение от Alexey9891 Посмотреть сообщение
а потом когда это количество станет известным делать каждому resize(). Так?
Именно так
0
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 15:59  [ТС]
Цитата Сообщение от Anvis Посмотреть сообщение
push_back
Страуструп пишет: "Каждый раз при вызове push back() вектор s увеличивается на один элемент, который добавляется в его конец."
При вызове конструктора я уже знаю всё количество, прикажете в for крутить push back() для всех векторов?

Добавлено через 2 минуты
Цитата Сообщение от KSergey9 Посмотреть сообщение
Именно так
Блин, а я думал эта идея шикарна:
Цитата Сообщение от Alexey9891 Посмотреть сообщение
В описании класса я ещё не знаю сколько диодов, поэтому храню там только указатель на вектор связанный с этим количеством. Когда пользователь вызовет конструктор, он в вызове укажет количество светодиодов, и я в конструкторе создам вектор через new под необходимое количество диодов.
0
Заблокирован
19.02.2025, 16:02
Мне не причудилось.
Это в функции столько параметров?

А где код с самим ресайзом и использования после этого?

Добавлено через 1 минуту
Блин, это конструктор. Вопрос тот же.
0
-11 / 0 / 1
Регистрация: 02.09.2015
Сообщений: 76
19.02.2025, 16:03  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
Это в функции столько параметров?
а чё? Универсальная, блин штука.
0
Заблокирован
19.02.2025, 16:08
Alexey9891, странно, что данные которые по умолчанию, инициализируются в конструкторе.
Это потенциально опасно. В лучшем случае будут повторения от конструктора к конструктору.

C++
1
2
3
4
struct A{
 int d1{}, d2{}, d3{5}; // инициализированы по умолчанию 
 std::vector<std::uint8_t> v; // то же что и v{}
};
0
86 / 60 / 12
Регистрация: 06.06.2013
Сообщений: 216
19.02.2025, 16:08
Ну, собственно, да, как говорять французы, пуркуа бы и не па. А как вы потом заполняете вектор, если не через for? Конкретно в случае с uint8_t оно без разницы, но вот если в будущем создадите вектор для хранения пачки тяжелых экземпляров классов, сделаете ему ресайз, а затем начнете заполнять, программа сначала создаст вектор нужной длины, заполнит его классами через конструкторы по умолчанию, и только потом начнет копировать в них заданные вами настройки. Гораздо выгоднее будет объявить вектор, затем зарезервировать через reserve объем памяти, соответствующий его будущему размеру, а потом заполнять его классами сразу с требуемыми настройками через push_back.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
19.02.2025, 16:08
Помогаю со студенческими работами здесь

STL::vector (метод resize)
Здравствуйте ,у меня возник один вопрос по поводу метода resize() ... Вот пример кода if (arr.empty()) //Если...

Непонятная ошибка при вызове std::vector::resize
Недавно заметил непонятную ошибку при вызове метода resize(); Я так и не понял как правильно создавать таблицы с динамически...

vector в структуре: возможно?
могу ли я, объявляя структуру, написать так: struct A { vector&lt;char&gt; v; ......... }; ?

Рандомный выбор элементов vector-а
есть вектор vector&lt;string&gt; s =&quot; a1a, a2a, a3a, a4a, a5a&quot; как мне сделать рандомный выбор допустим 2 подстрок, что бы на выходе получить...

"Преобразование" из uint8_t в byte []
Здравствуйте, такой вопрос Нужно преобразовать значение из uint8_t в массив byte То есть: Дано uint8_t s; byte d; s=15; (в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Ниже машинный перевод статьи The Thinkpad X220 Tablet is the best budget school laptop period . Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы,. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru