Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
использую код на c в него нужно передать указатель на char . я его получаю с помощью c_str у std::string . такой указатель жив пока живет строка, от куда я его поулчил и пока она с того момента не изменилась. но вот если эта строка живет (и никто её не изменяет) в std::vector - то будет ли работать c_str или накроется при каком-нибудь std::find ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2015, 21:45 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
alexy_blackиспользую код на c в него нужно передать указатель на char . я его получаю с помощью c_str у std::string . Указатель на char невозможно получить с помощью функции c_str(), потому что она возвращает const char* Чтобы получить указатель на буфер std::string надо взять адрес первого элемента строки или использвать функцию front() акой указатель жив пока живет строка, от куда я его поулчил и пока она с того момента не изменилась. -- ДА. но вот если эта строка живет (и никто её не изменяет) в std::vector - то будет ли работать c_str или накроется при каком-нибудь std::find? Это не важно, где живёт сама строка. Но разумеется, она не должна уничтожаться. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2015, 00:53 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
конечно не должна уничтожаться... вопрос появился из невозможности нормлаьного использования std::vector<std::auto_ptr<foo>> ( std::vector<std::unique_ptr<foo>> ), потому что некторые алгоритмы работы с контейнерами и реализация контейнера будут копировать объекты, а при копировании исходный объект удалиться (в случаи этих ptr'ов). вот я и подумал: что останется в векторе, копия когда-нибдуь и ли всегда будет исходная строка? ну да, const , но даже если я возьму адрес начала строки ( std::string::data() вроде подходит ), то вопрос остается актуальным :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.10.2015, 14:34 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
alexy_black, не используйте auto_ptr. Он сейчас запрещен к использованию, и разработчики большинства реализаций стандартных библиотек сделали всё, чтобы auto_ptr нельзя было использовать на стандартных контейнерах - должны порождаться ошибки компиляции. Если вам необходимо монопольное владение ресурсом, используйте unique_ptr. Если нужно совместное ("разделяемое") владение - используйте shared_ptr. Какая разница, где живёт эта строка? Лишь бы она не вышла за область своей видимости (и не была "почищена" деструктором). ЗЫ Приведите простой кейс использования. А то абстрактно советовать можно только коня в вакууме. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2015, 00:04 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
Так и не понял задачи. Есть коллекция из строк, надо чтобы где-то неизвестное время болтался указатель на данные из этих строк одновременно с действиями над этой коллекцией? То есть туда лезут несколько потоков? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2015, 10:06 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
это асинхронный веб сервер. я сделал интерфейс на c++ но код сервера написан на с (libh2o). отправка происходит асинхронно, поэтому я копирую некоторые строки, когда пользователь вызывает функцию отправки, потом, когда-то, они будут отправлены. ну смысл такой. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. да, про auto_ptr знаю, не использую :) просто я напаролся один раз (давно) на конструкции вида std::vector<std::auto_ptr<foo>> :) то есть хранились они хорошо, но как только применил какой-то алгоритм, все пропадало :) это пому что этот алгоритм там внутрях что-то копировал, а auto_ptr передавал владение копии, которая уничтожалась вместе с объектом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.10.2015, 23:24 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
alexy_black, не делайте так: alexy_black... Код: plaintext 1. 2. 3. 4. ... Время "валидности" полученного вами указателя ограничено строкой "const char* pointer_to_c_str = strings[0].c_str();". Ровно до точки с запятой. После этой строки может произойти инвалидация указателя (стандарт не гарантирует вам сохранение его "валидности"). Это происходит не часть, и потому такой код довольно долго работает... но в один прекрасный момент может выстрелить. Ваш пример можно переделать к "законному" виду: Код: plaintext 1. Здесь указатель живёт сколько надо. Вот только в данном примере это не имеет смысла (т.к. cout прекрасно понимает std::string). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2015, 00:39 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
BagaBaga, это ответ на мой вопрос, спасибо :) я раньше эту функцию c_str() почти никогда не использовал, так что не знаю тонокстей работы с ней. да, я знаю что cout понимает std::string - но в коде я не cout использую, а api функцию на c, которая ничего не понимает кроме char* . это просто для "примера использования". а выстреливает она почему? потому что буфер, на который указатель нацелен, сразу же исчезает или потому что он не известно когда исчезает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2015, 13:18 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
alexy_black, такое поведение - не особенность функции c_str. Что c_str делает? Возвращает указатель на внутреннюю структуру (буфер). Сколько этот указатель будет валидным? Не более, чем "жива" сама структура (пока она не уйдёт из области видимости). Но может быть "испорчена" и ранее, если происходили изменения структуры (например, "склеивали" строки и для новой "итоговой" строки пришлось получать новый буфер). Что делать? Во-первых, не менять строку после того, как получил указатель (иначе мы его можем инвалидировать). Теперь осталось разобраться со временем жизни. Какое оно? Что сделает компилятор вот на это: Код: plaintext 1. 2. 3. ? Он может сделать, например, вот так Код: plaintext 1. 2. 3. 4. Почему? Что нам гарантирует стандарт? - Что конструктор обязательно будет вызван до первого "использования" экземляра класса. Скорее всего, в месте объявления, но не обязательно. - Что деструктор будет вызван перед "окончанием" области видимости. Где-то перед, а не обязательно "точно вот перед выходом". Но обязательно после последнего "использования". Компилятор имеет право переупорядочивать инструкции. Например, в целях оптимизации скорости выполнения. И в данном примере он может (но не обязано - без гарантий) вызвать деструктор после последнего использования (str.c_str()), но до нашего обращения к "нутру" этого объекта (*ch). Компилятор спокойно отслеживает все обращения типа str.чего_то_там, но различного рода косвенные обращения он отследить не в состоянии. В результате наше последующее обращение по полученному через c_str() адресу может быть невалидным - этот адрес может быть уже освобождён (вызовом деструктора) и повторно использован кем-либо ещё. Почему может выстрелить? Потому что эта память может быть кем-то использована на запись и мы пользуем "чужую", уже "подпорченную" область. В большинстве случаев эта память "лежит спокойно" и никому не достаётся - в результате мы спокойно видим старые и даже неподпорченные данные. Вероятность порчи этих данных зависит от - опций компиляции, способа использования приложения. Если опция компиляции не больше -О2, то переупорядочивание вызова деструктора обычно (но - без гарантий) не происходит. Если -O3, то почти наверняка переупорядочит. Если приложение многопоточное и-или интенсивно использует память - то больше шансов, что память, из которой мы читает по "внутреннему" указателю, будет выделена для конкурирующего потока. И вот тогда приложение сломается, получая вместо "хорошей" строки "непонятный мусор". Так что если коротко ответить на вопрос: одному компилятору известно, когда он исчезает ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.10.2015, 23:07 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
Я думал, что: Local objects explicitly declared auto or register or not explicitly declared static or extern have automatic storage duration. The storage for these objects lasts until the block in which they are created exits. Означает, что объект живёт до завершения блока, в котором он объявлен. Однако если это не так, то может кто-нибудь объяснить на каком основании должно работать RAII? Вот мы пишем скажем: Код: plaintext 1. 2. 3. 4. Но получается, что оно может отработать и так: Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2015, 10:50 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
Гость123, с семафорами, атомиками и многопоточным программированием всё гораздо сложнее - там нужно понимать C++ memory model (в частности барьеры). Про RAII. Суть RAII - "обернуть" незащищённый ресурс и везде вместо него использовать обёртку. Тот же unique_ptr существует (гарантированно существует) до тех пор, пока к нему есть "обращения". Вы не можете оберныть "грязный" указатель в умный и продолжать безнаказанно пользоваться "грязным" - рано или поздно выстрелит. Если сомневаетесь, что компилятор "вычищает" и "переупорядочивает"... скомпилируйте простенький код с самыми агрессивными настройками оптимизации и без них и посмотрите в дизассемблере. Там вас уж точно ни кто не обманет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.10.2015, 11:30 |
|
||
|
копирование в std::vector
|
|||
|---|---|---|---|
|
#18+
BagaBagaЧто сделает компилятор вот на это: Код: plaintext 1. 2. 3. ? Он может сделать, например, вот так Код: plaintext 1. 2. 3. 4. Нет, не может. BagaBagaКомпилятор имеет право переупорядочивать инструкции. Машинные инструкции, а не statement-ы языка, и только так, чтобы наблюдаемое поведение программы не изменилось. BagaBagaИ в данном примере он может (но не обязано - без гарантий) вызвать деструктор после последнего использования (str.c_str()), но до нашего обращения к "нутру" этого объекта (*ch).Нет, не может. Гость123Я думал, что: Local objects explicitly declared auto or register or not explicitly declared static or extern have automatic storage duration. The storage for these objects lasts until the block in which they are created exits. Означает, что объект живёт до завершения блока, в котором он объявлен. Однако если это не так, то может кто-нибудь объяснить на каком основании должно работать RAII?RAII работает на том основании, что BagaBaga написал неправду :). Гость123Вот мы пишем скажем: Код: plaintext 1. 2. 3. 4. Но получается, что оно может отработать и так: Код: plaintext 1. 2. 3. 4. 5. Нет, не может. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.11.2015, 01:10 |
|
||
|
|

start [/forum/topic.php?fid=57&tid=2018766]: |
0ms |
get settings: |
12ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
159ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 283ms |
| total: | 531ms |

| 0 / 0 |
