Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как храниться struct в vector / 25 сообщений из 26, страница 1 из 2
09.01.2019, 10:46
    #39757017
Alimkulov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
Привет всем.
Нужна ваша помощь в понимание 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
09.01.2019, 10:54
    #39757026
Alimkulov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
...
Рейтинг: 0 / 0
09.01.2019, 11:00
    #39757032
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
это временный объект уничтожается, который ты создаешь, чтобы поместить его копию в push_back

используй emplace_back(в твоем случае без параметров) и картина станет более прозрачная.
...
Рейтинг: 0 / 0
09.01.2019, 11:12
    #39757037
Alimkulov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
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
09.01.2019, 11:52
    #39757065
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
Alimkulov,

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

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

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

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

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

К тому же, всегда можно поступить как Qt-шники в своей архитектуре -- использовать pImpl везде, где можно. sizeof типов не больше 16 байт на x64,
то есть data-ptr + vtable-ptr. И сразу нет проблемы с копированием, а заодно и implicit sharing.
Но у этого тоже есть своя цена -- лишний new при каждом создании объекта такого класса для Private-класса.
...
Рейтинг: 0 / 0
09.01.2019, 12:23
    #39757096
NekZ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
AlimkulovNekZ,
Я согласен с Вами. Если меньше кол-во struct, то vector лучше подходить.
Если заранее знаешь сколько объектов у тебя будет, вызови сначала vector.reserve(...).
...
Рейтинг: 0 / 0
09.01.2019, 12:40
    #39757105
Alimkulov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
Стал еще понятнее после добавление явно 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
09.01.2019, 12:47
    #39757109
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.
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
09.01.2019, 12:55
    #39757116
alex_k
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как храниться struct в vector
Cerebrum,

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

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

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


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

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

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

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

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


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

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

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

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

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

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


ЭЭЭЭ

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

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

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

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


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