powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как храниться struct в vector
25 сообщений из 26, страница 1 из 2
Как храниться struct в vector
    #39757017
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет всем.
Нужна ваша помощь в понимание struct в vector.

Вот мой маленький тест:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
  int rectIndex;

struct Rect {
	int x;
	int y;
	int _index;
	Rect() {
		_index = rectIndex;
		printf("ctor %d\n", _index);
	}
	~Rect() {
		printf("dtor %d\n", _index);
	}
};

void FillVector()
{
	std::vector<Rect> v;

	rectIndex = 0;
        // new Rect created with default constructor
	v.push_back(Rect());
	v[0].x = 10;
	v[0].y = 10;

	rectIndex++;
        // new Rect created with default constructor
	v.push_back(Rect());
	v[1].x = 10;
	v[1].y = 10;

	rectIndex++;
        // new Rect created with default constructor
	v.push_back(Rect());
	v[2].x = 10;
	v[2].y = 10;

	rectIndex++;
        // new Rect created with default constructor
	v.push_back(Rect());
	v[3].x = 10;
	v[3].y = 10;
}


int main()
{
	FillVector();
	getchar();
	return 0;
}



Посмотрите на рисунку, почему destructor вызывается лишний раз?
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757026
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757032
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
это временный объект уничтожается, который ты создаешь, чтобы поместить его копию в push_back

используй emplace_back(в твоем случае без параметров) и картина станет более прозрачная.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757037
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_k,
Спасибо за ответ!

Оказывается vector::emplace_back() добавляет элемент, созданный на месте, в конец вектора да?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
void FillVector()
{
	std::vector<Rect> v;

	rectIndex = 0;
	v.emplace_back();
	v[0].x = 10;
	v[0].y = 10;

	rectIndex++;
	v.emplace_back();
	v[1].x = 10;
	v[1].y = 10;

	rectIndex++;
	v.emplace_back();
	v[2].x = 10;
	v[2].y = 10;

	rectIndex++;
	v.emplace_back();
	v[3].x = 10;
	v[3].y = 10;

	printf("\n\n dtor of vector\n");
}



Все равно есть лишний вызовы dtor!
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757065
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

vector расширяется динамически с экспоненциальным приростом размера.
Когда вектору не хватает памяти под новый элемент, он вынужден делать реаллокацию и перемещать все объекты.
Но, нельзя просто так взять и сделать memcpy на все объекты в векторе, так как это чревато dangling reference/pointer'ами в клиентском коде.
Следовательно, vector поступает хитро, он берёт и сначала проверяет, есть ли у твоего типа noexcept move ctor. Если есть, использует его
для перемещения объектов в новую область памяти через placement new. Если нет, использует copy-ctor. И именно поэтому copy-ctor и move-ctor
являются обязательными для вектора и проверяются в компайл-тайме через трейты. Ну и noexcept у них крайне желателен.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757066
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZНо, нельзя просто так взять и сделать memcpy на все объекты в векторе
Забыл упомянуть, что memcpy всё же используется, но только для POD-типов.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757069
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И после того, как vector переместил/скопировал все объекты в новую область памяти, он, естественно, вызывает dtor'ы у старых объектов.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757071
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
отсюда вывод - нефиг хранить в векторе большие структуры данных, вместо них надо хранить указатели на них
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757073
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ,
Спасибо вам, освободили меня от многих сомнений. Теперь все понятно.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757074
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,
Спасибо за ответ. Вы совершенно правы. Да, так и надо!
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757078
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrumотсюда вывод - нефиг хранить в векторе большие структуры данных, вместо них надо хранить указатели на них
Не совсем правильный вывод. Можно подобрать более подходящий контейнер, но следует помнить, что нет идеальных контейнеров,
выбор контейнера всегда -- компромисс между удобством сопровождения, временной и простанственной сложностями.
Например, откажется от контейнера, как ты предлагаешь -- просядешь по удобству сопровождения, зато всё остальное будет ок.
Всегда всё зависит от окружающих условий.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757082
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ,

безусловно, использование контейнеров еще не означает что мозги надо отключать.
можно и с указателями накосячить: выделить память объекта через new/malloc, затолкать адрес в контейнер, а потом забыть ее почистить.

В этом случаем можно использовать для хранения smart поинтеры, но тут опять - вопрос реализации.
Идеального варианта как всегда не существует.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757084
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ,
Я согласен с Вами. Если меньше кол-во struct, то vector лучше подходить.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757088
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alimkulov,

Зарезервируй память в векторе на то количество элементов которое предполагается использовать и исчезнут все лишние деструкторы.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757093
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCc,
К сожалению, размер vector заранее не известно, но спасибо за внимание!
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757094
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,

Вообще, new/malloc'ом уже мало кто пользуется в новом коде, smart-pointer'ы рулят, raw-pointer'ы, как известно, error-prone.

К тому же, всегда можно поступить как Qt-шники в своей архитектуре -- использовать pImpl везде, где можно. sizeof типов не больше 16 байт на x64,
то есть data-ptr + vtable-ptr. И сразу нет проблемы с копированием, а заодно и implicit sharing.
Но у этого тоже есть своя цена -- лишний new при каждом создании объекта такого класса для Private-класса.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757096
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlimkulovNekZ,
Я согласен с Вами. Если меньше кол-во struct, то vector лучше подходить.
Если заранее знаешь сколько объектов у тебя будет, вызови сначала vector.reserve(...).
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757105
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стал еще понятнее после добавление явно copy ctor. А до этого был неявное копирование ctor.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
struct Rect {
	int x;
	int y;
	int _index;
	Rect() {
		_index = rectIndex;
		printf("ctor [ index: %d ]\n", _index);
	}

	Rect(const Rect& _right)
		: x(_right.x),
		y(_right.y),
		_index(_right._index)
	{
		printf("copy ctor [ index: %d ]\n", _index);
	}

	~Rect() {
		printf("dtor [ index: %d ]\n", _index);
	}
};
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757109
Alimkulov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
struct Rect {
	int x;
	int y;
	int _index;
	bool isCopy;

	Rect()
		:_index(rectIndex),
		isCopy(false)
	{		
		printf("ctor [ index: %d ]\n", _index);
	}

	Rect(const Rect& _right)
		: x(_right.x),
		y(_right.y),
		_index(_right._index),
		isCopy(true)
	{
		printf("copy ctor [ index: %d ]\n", _index);
	}

	~Rect() {
		if (isCopy)
			printf("dtor of copy [ index: %d ], \n", _index);
		else
			printf("dtor [ index: %d ], \n", _index);
	}
};
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757116
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum,

Если хранить указатели, тогда последовательный перебор объектов может давать много промахов в кэше. Надо смотреть, что хуже. Если контэйнер заполняется один раз, а проходится много раз, то лучше стерпеть реаллокацию(а еще лучше, спрогнозировать количество и зарезервировать память).

К тому же, существуют мув конструкторы, которые могут сэкономить работу при реаллокации объектов.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757126
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_k,

это мы с тобой это понимаем, move'ы-хренувы, а теперь попробуй объяснить это новичку, который пришел на форум с детсадовским вопросом, а получил объем информации на докторскую диссертацию


Я считаю, что пока ты учишь язык, нужно чтобы тебе было понятно что ты делаешь, что видишь в коде, что получаешь в run-time. Без всяких наворотов. KISS принцип - наше все, а не smart pointer'ы и move'ы!

Когда разберешься как это работает в low level, тогда уже сам сможешь выбрать что тебе юзать в конечной реализации, если за время обучения у тебя вообще все желание не пропадет к чертовой матери.
оффтопикЗа последние десять лет в стандарте языка появилось столько всякого говна, что порог вхождения, который якобы должен стать ниже, повысился в разы, по сравнению с классическим C++. Потому что стало столько неявного и скрытого под капотом, что не дай бог ты попытаешься написать что-то сам, не так как это в std/stl - отстрелишь не только ногу, голову снесешь сразу! Не удивительно что доля языка год от года сокращается, не смотря на все эти нововведения.

Складывается ощущение, что разработчики стандарта заварили кашу в С++11, а теперь пилят инструменты для того, чтобы удерживать свой код хоть в каком-то более-менее приличном состоянии, т.е. пилят новые фичи исключительно (за редким исключением) для себя, выдавая их как новшество в стандарте. Идет расхолаживание С++ программистов старой школы и молодых в частности. Из номального языка стараются сделать очередной basic.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757131
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cerebrum
оффтопикЗа последние десять лет в стандарте языка появилось столько всякого говна, что порог вхождения, который якобы должен стать ниже, повысился в разы, по сравнению с классическим C++. Потому что стало столько неявного и скрытого под капотом, что не дай бог ты попытаешься написать что-то сам, не так как это в std/stl - отстрелишь не только ногу, голову снесешь сразу! Не удивительно что доля языка год от года сокращается, не смотря на все эти нововведения.

Складывается ощущение, что разработчики стандарта заварили кашу в С++11, а теперь пилят инструменты для того, чтобы удерживать свой код хоть в каком-то более-менее приличном состоянии, т.е. пилят новые фичи исключительно (за редким исключением) для себя, выдавая их как новшество в стандарте. Идет расхолаживание С++ программистов старой школы и молодых в частности. Из номального языка стараются сделать очередной basic.

ответ на оффтопик
Баттхёрт ниасилятора энд насин мо эбав.
Тебя же никто не заставляет писать всё строго по стандарту C++11/14/17/20. Обратная совместимость по-прежнему сохраняется.
Другое дело, что теперь у тебя появился более широкий выбор средств как выразить свои решения в коде. Но как только диапазон вариантов
для выбора расширяется, ниасилятор сразу начинает реветь и хныкать "верните всё взад!". К тому же, новшества все обкатываются заранее в boost'е,
так что сюрпризов там нет. И ещё наконец-то появились Core Guidelines, на которые ты можешь опираться, чего раньше не было.
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757142
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex_kЕсли хранить указатели, тогда последовательный перебор объектов может давать много промахов в кэше. Надо смотреть, что хуже. Если контэйнер заполняется один раз, а проходится много раз, то лучше стерпеть реаллокацию(а еще лучше, спрогнозировать количество и зарезервировать память).


Тут все зависит от размера самого объекта.

Если объекты огромные - то лучше хранить указатели

Если мелкие - то да - как Вы описали
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757156
Фотография Cerebrum
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZ,тебе показалось, что я неосилятор,
я довольно много и успешно юзаю все, что мне надо из С++17 вплоть до ANSI С, я говорю лишь о том, что раньше можно было нормально писать и без Code/Core/Best Practice/Guidline'ов, после изучения пары букварей по языку, а теперь без поводырей уже никак, что не способствует нормальному вхождению новичка в язык, который и без этого непростой для освоения.

Что касается выбора - это может и хорошо, когда ты на 100% знаешь, что не выберешь неправильно.
Для большинства наличие выбора это уже камень преткновения, который как бы намекает, что как не сделай все равно будет полумера. Даже после того, как выбор сделан нет уверенности в правильности принятого решения.

Даже само то, что я, как разработчик, теперь еще должен думать о каких-то cache misses (про которые раньше почему-то все упорно молчали, а сейчас вдруг стало трендом - с чего бы это? уж не от того ли, что появился оверхэд из-за всяких оберткок) говорит о многом.

Получается чем выше предлагает нам язык уровень абстракции, тем ниже приходится заглядывать под капот, вплоть до, а не перелетаю ли я L1 кэш . Так и до паранойи недалеко. ООП теперь не модно, давайте пилить Data Oriented, т.е. все по сути опять сводится к банальному С со структурами. Ну и стоило оно того, мутить все это?
...
Рейтинг: 0 / 0
Как храниться struct в vector
    #39757189
semen.s.semen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
NekZДаже само то, что я, как разработчик, теперь еще должен думать о каких-то cache misses (про которые раньше почему-то все упорно молчали, а сейчас вдруг стало трендом - с чего бы это?


ЭЭЭЭ

Как мне казалось это от задачи зависит

Если, скажем, Вы пишите свои высокоскоростные коллекции или системы обработки данных в реальном времени то понимание cache misses это строго обязательная процедура

Если же кодите CRUD формочки - то наверное нет.

При этом Ява это или С++ роли не играет.
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как храниться struct в vector
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]