Здравствуйте, Аноним, Вы писали:
А>Что-то не могу сообразить, помогите пожалуйста: А>
А>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
элементов остались прежними
Здравствуйте, mraleh, Вы писали:
M>Здравствуйте, Анатолий Широков, Вы писали: M>Можно сэкономить на одном вызове и избежать лишних перелокаций. M>
M>v.resize(m);
M>v.insert(v.end(), p, p+n);
M>
M>К тому же это по-моему будет эффективней.
В методе, который предложил Анатолий Широков, выделение памяти происходит 1 раз. В вашем же варианте — вполне может быть, что и 2 раза. Так что утверждение, что такой код поможет "избежать лишних перелокаций" не совсем корректо.
Хотя очень многое зависит от того, что понимается под "лишними перелокациями"
Здравствуйте, Bell, Вы писали:
B>В методе, который предложил Анатолий Широков, выделение памяти происходит 1 раз. В вашем же варианте — вполне может быть, что и 2 раза. Так что утверждение, что такой код поможет "избежать лишних перелокаций" не совсем корректо. B>Хотя очень многое зависит от того, что понимается под "лишними перелокациями"
Хм, насколько я знаю, при resize() в сторону уменьшения лишняя емкость не освобождается.
Можно в этом убедиться:
Не зря Мейерс в "Effective STL" для уменьшения емкости предлагает "фокус с перестановкой".
А по вопросам эффективности, я изхожу из того допущения, что методы контейнера реализованы
эффективнее общих алгоритмов. Во всяком случае я на это надеюсь
Здравствуйте, 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);//при этой вставке вполне может произойти перераспределение памяти.
Так что я по прежнему утверждаю, что метод А.Ш. эффективней.
Здравствуйте, 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...
Здравствуйте, 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 элементов) — это первое распределение. Вставка также может привести к перепаспределению (не всегда, но может), и это уже второе перераспределение.
L>на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое... L>все зависит от величины N
Нет. Блочная вставка (да и вообще все варианты insert для std::vector) работает "умнее" — перераспределение (если оно нужно) выполняется только один раз.
Здравствуйте, Анатолий Широков, Вы писали:
АШ>Просто mraleh использует посыл:
АШ>
АШ>Размерность вектора неизвестна, но не меньше m.
АШ>, который прозвучал в первом посте этой ветки и именно опираясь на это вел дискуссию.
АШ>Исходя из этого оба варианта используют одно перераспределение и равнозначны по скорости.
Да, это меняет дело. Был невнимателен. Постараюсь исправиться
Здравствуйте, Libra, Вы писали:
L>Здравствуйте, mraleh, Вы писали:
M>>Здравствуйте, Bell, Вы писали:
B>>>Ваш вариант. B>>>
B>>>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение памяти.
B>>>
M>>Да конечно, оно может произойти, но только <b>Один раз</b> (также как и при reserve()), где второе перераспределение ? Может я чего-то не понимаю ?
L>на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое...
Это возможно для одноэлементного insert(), для интервального такого не должно быть.
B>>>>v.insert(v.end(), p, p+n);//при этой вставке вполне может произойти перераспределение
B>>>>памяти.
B>>>>
L>>на самом деле может быть и не только вотрое перераспределение, а тиретье и четвертое...
m> Это возможно для одноэлементного insert(), для интервального такого не должно быть.
Если точнее, то для интервальной вставки перераспределение тоже возможно и зависит от итератора.
Но в данном случае это не существенно.
Здравствуйте, Андрей Галюзин, Вы писали:
АГ>Если точнее, то для интервальной вставки перераспределение тоже возможно и зависит от итератора. АГ>Но в данном случае это не существенно.
Я и имел в виду данный случай.
АГ>-- АГ>aga