копирование/вставка в вектор
От: Аноним  
Дата: 30.01.04 15:51
Оценка:
Что-то не могу сообразить, помогите пожалуйста:
char *p; // массив
выделяется память для p, заполняется

vector<char> v1;

необходимо скопировать n элементов из массива в вектор, начиная с m элемента вектора.
Размерность вектора неизвестна, но не меньше m.

Если бы v1 был массивом это было бы так:
memcpy(v1 + m, p, n);
Re: копирование/вставка в вектор
От: sath Россия  
Дата: 30.01.04 15:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Что-то не могу сообразить, помогите пожалуйста:

А>
А>char *p; // массив
А>выделяется память для p, заполняется

А>vector<char> v1;

А>

А>необходимо скопировать n элементов из массива в вектор, начиная с m элемента вектора.
А>Размерность вектора неизвестна, но не меньше m.

А>Если бы v1 был массивом это было бы так:

А>memcpy(v1 + m, p, n);

char *p;

p = new char[20];
...


std::vector<char> ms;
ms.assign(p,p+20);
Re[2]: копирование/вставка в вектор
От: Аноним  
Дата: 30.01.04 16:36
Оценка:
Здравствуйте, sath, Вы писали:

S>p = new char[20];

S>...


S>std::vector<char> ms;

S>ms.assign(p,p+20);
Не пойдет, так мы перепишим весь вектор, а надо чтобы первые m
элементов остались прежними
Re: копирование/вставка в вектор
От: Анатолий Широков СССР  
Дата: 30.01.04 16:56
Оценка: 1 (1)
либо так:

v.resize(m + n);

vector<char>::iterator bi = v.begin();

std::advance(bi, m);

std::copy(p, p + n, bi);



либо так:


v.reserve(m + n);
v.resize(m);

std::copy(p, p + n, std::back_inserter(v));
Re[2]: копирование/вставка в вектор
От: Аноним  
Дата: 30.01.04 18:16
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>
АШ>v.reserve(m + n);
АШ>v.resize(m);

АШ>std::copy(p, p + n, std::back_inserter(v));
АШ>

а reserve обязательно делать, зачеи он нужен ?
Re[3]: копирование/вставка в вектор
От: Анатолий Широков СССР  
Дата: 30.01.04 19:08
Оценка: +1
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Анатолий Широков, Вы писали:


АШ>>
АШ>>v.reserve(m + n);
АШ>>v.resize(m);

АШ>>std::copy(p, p + n, std::back_inserter(v)); // (*)
АШ>>

А>а reserve обязательно делать, зачеи он нужен ?

Нет, не обязательно, но к чему лишние переаллокации памяти во время копирования (*).
Re[4]: копирование/вставка в вектор
От: mraleh Россия  
Дата: 31.01.04 06:31
Оценка: 1 (1)
Здравствуйте, Анатолий Широков, Вы писали:
Можно сэкономить на одном вызове и избежать лишних перелокаций.
v.resize(m);
v.insert(v.end(), p, p+n);

К тому же это по-моему будет эффективней.
... << RSDN@Home 1.1.0 stable >>
Re[5]: копирование/вставка в вектор
От: Bell Россия  
Дата: 02.02.04 07:34
Оценка:
Здравствуйте, mraleh, Вы писали:

M>Здравствуйте, Анатолий Широков, Вы писали:

M>Можно сэкономить на одном вызове и избежать лишних перелокаций.
M>
M>v.resize(m);
M>v.insert(v.end(), p, p+n);
M>

M>К тому же это по-моему будет эффективней.

В методе, который предложил Анатолий Широков, выделение памяти происходит 1 раз. В вашем же варианте — вполне может быть, что и 2 раза. Так что утверждение, что такой код поможет "избежать лишних перелокаций" не совсем корректо.
Хотя очень многое зависит от того, что понимается под "лишними перелокациями"
Любите книгу — источник знаний (с) М.Горький
Re[6]: копирование/вставка в вектор
От: mraleh Россия  
Дата: 04.02.04 05:27
Оценка:
Здравствуйте, Bell, Вы писали:

B>В методе, который предложил Анатолий Широков, выделение памяти происходит 1 раз. В вашем же варианте — вполне может быть, что и 2 раза. Так что утверждение, что такой код поможет "избежать лишних перелокаций" не совсем корректо.

B>Хотя очень многое зависит от того, что понимается под "лишними перелокациями"

Хм, насколько я знаю, при resize() в сторону уменьшения лишняя емкость не освобождается.
Можно в этом убедиться:
vector<char> v(1000000);
cout << "Size: " << v.size() << endl;
cout << "Capacity: " << v.capacity() << endl;
v.resize(5);
cout << "Size: " << v.size() << endl;
cout << "Capacity: " << v.capacity() << endl;

Не зря Мейерс в "Effective STL" для уменьшения емкости предлагает "фокус с перестановкой".

А по вопросам эффективности, я изхожу из того допущения, что методы контейнера реализованы
эффективнее общих алгоритмов. Во всяком случае я на это надеюсь
... << RSDN@Home 1.1.0 stable >>
Re[7]: копирование/вставка в вектор
От: Bell Россия  
Дата: 04.02.04 07:48
Оценка: +1
Здравствуйте, mraleh, Вы писали:

M>Хм, насколько я знаю, при resize() в сторону уменьшения лишняя емкость не освобождается.

Это так, но речь идет не о resize.
Еще раз.
Метод А.Ш.

v.reserve(m + n);//Один раз резервируем память
v.resize(m);//теперь v.size() == m, v.capacity() == m + n

std::copy(p, p + n, std::back_inserter(v)); // push_back() не приводит к перераспределению.


Ваш вариант.
v.resize(m);//теперь v.size() == m, v.capacity() может быть и меньше, чем m + n
v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение памяти.


Так что я по прежнему утверждаю, что метод А.Ш. эффективней.
Любите книгу — источник знаний (с) М.Горький
Re[8]: копирование/вставка в вектор
От: mraleh Россия  
Дата: 04.02.04 08:12
Оценка:
Здравствуйте, Bell, Вы писали:

B>Ваш вариант.

B>
B>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение памяти.
B>

Да конечно, оно может произойти, но только <b>Один раз</b> (также как и при reserve()), где второе перераспределение ? Может я чего-то не понимаю ?
... << RSDN@Home 1.1.0 stable >>
Re[9]: копирование/вставка в вектор
От: Libra Россия  
Дата: 04.02.04 09:06
Оценка:
Здравствуйте, mraleh, Вы писали:

M>Здравствуйте, Bell, Вы писали:


B>>Ваш вариант.

B>>
B>>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение памяти.
B>>

M>Да конечно, оно может произойти, но только <b>Один раз</b> (также как и при reserve()), где второе перераспределение ? Может я чего-то не понимаю ?

на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое...
все зависит от величины N
если в процессе вставки нового элемента операцией insert в выделенном в vector под хранение буффере не окажеться свободного места, то произойдет очередное перевыделение памяти...

в варианте предложенн А.Ш. выделение происходит всего один раз, это обсолютно точно
Species come and go, but the earth stands forever fast...
Re[9]: копирование/вставка в вектор
От: Bell Россия  
Дата: 04.02.04 09:36
Оценка:
Здравствуйте, mraleh, Вы писали:

M>Здравствуйте, Bell, Вы писали:


B>>Ваш вариант.

B>>
B>>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение памяти.
B>>

M>Да конечно, оно может произойти, но только <b>Один раз</b> (также как и при reserve()), где второе перераспределение ? Может я чего-то не понимаю ?

Что-то нету взаимопонимания
Попрбую еще раз.
В варианте А.Ш. перед началом работы один раз вызывается reserve(), в результате чего один раз производится выделение памяти. Последуюшие операции (resize и push_back) не приводят к повторным перераспределениям, т.к. памяти в векторе достаточно.

В твоем варианте сначала делается resize(m) (хотя уже известно, что памяти требуется для m+n элементов) — это первое распределение. Вставка также может привести к перепаспределению (не всегда, но может), и это уже второе перераспределение.

Надеюсь, точки над i расставлены
Любите книгу — источник знаний (с) М.Горький
Re[10]: копирование/вставка в вектор
От: Bell Россия  
Дата: 04.02.04 09:55
Оценка:
Здравствуйте, Libra, Вы писали:


L>на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое...

L>все зависит от величины N
Нет. Блочная вставка (да и вообще все варианты insert для std::vector) работает "умнее" — перераспределение (если оно нужно) выполняется только один раз.
Любите книгу — источник знаний (с) М.Горький
Re[10]: копирование/вставка в вектор
От: Анатолий Широков СССР  
Дата: 04.02.04 10:09
Оценка:
Просто mraleh использует посыл:

Размерность вектора неизвестна, но не меньше m.


, который прозвучал в первом посте этой ветки и именно опираясь на это вел дискуссию.

Исходя из этого оба варианта используют одно перераспределение и равнозначны по скорости.
Re[11]: копирование/вставка в вектор
От: Bell Россия  
Дата: 04.02.04 10:15
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Просто mraleh использует посыл:


АШ>

АШ>Размерность вектора неизвестна, но не меньше m.


АШ>, который прозвучал в первом посте этой ветки и именно опираясь на это вел дискуссию.


АШ>Исходя из этого оба варианта используют одно перераспределение и равнозначны по скорости.


Да, это меняет дело. Был невнимателен. Постараюсь исправиться
Любите книгу — источник знаний (с) М.Горький
Re[10]: копирование/вставка в вектор
От: mraleh Россия  
Дата: 04.02.04 12:02
Оценка:
Здравствуйте, Libra, Вы писали:

L>Здравствуйте, mraleh, Вы писали:


M>>Здравствуйте, Bell, Вы писали:


B>>>Ваш вариант.

B>>>
B>>>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение памяти.
B>>>

M>>Да конечно, оно может произойти, но только <b>Один раз</b> (также как и при reserve()), где второе перераспределение ? Может я чего-то не понимаю ?

L>на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое...

Это возможно для одноэлементного insert(), для интервального такого не должно быть.
... << RSDN@Home 1.1.0 stable >>
Re[11]: копирование/вставка в вектор
От: Андрей Галюзин Украина  
Дата: 04.02.04 13:01
Оценка:
B>>>>
B>>>>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение
B>>>>памяти.
B>>>>


L>>на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое...


m> Это возможно для одноэлементного insert(), для интервального такого не должно быть.


Если точнее, то для интервальной вставки перераспределение тоже возможно и зависит от итератора.
Но в данном случае это не существенно.

--
aga
Posted via RSDN NNTP Server 1.7 "Bedlam"
Re[12]: копирование/вставка в вектор
От: mraleh Россия  
Дата: 04.02.04 18:54
Оценка:
Здравствуйте, Андрей Галюзин, Вы писали:

АГ>Если точнее, то для интервальной вставки перераспределение тоже возможно и зависит от итератора.

АГ>Но в данном случае это не существенно.
Я и имел в виду данный случай.

АГ>--

АГ>aga
... << RSDN@Home 1.1.0 stable >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.