Копирование из stringstream в array - Segmentation fault

191
28 октября 2018, 03:20
std::stringstream stream;
std::array<char, 1000> buffer;
long value = 100; // 8 bytes
stream.write(reinterpret_cast<const char*>(&value), sizeof(value));
std::copy(stream.str().begin(), stream.str().end(),&buffer[0]);
stream.write(reinterpret_cast<const char*>(&value), sizeof(value));
std::copy(stream.str().begin(), stream.str().end(),&buffer[0]); // Segmentation fault

stl_algbase.h

template<bool _IsMove>
    struct __copy_move<_IsMove, true, random_access_iterator_tag>
    {
      template<typename _Tp>
        static _Tp*
        __copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
        {
#if __cplusplus >= 201103L
      using __assignable = conditional<_IsMove,
                       is_move_assignable<_Tp>,
                       is_copy_assignable<_Tp>>;
      // trivial types can have deleted assignment
      static_assert( __assignable::type::value, "type is not assignable" );
#endif
      const ptrdiff_t _Num = __last - __first; // здесь значение отрциательное 
      if (_Num)
        __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
      return __result + _Num;
    }
    };
Answer 1

Метод std::stringstream::str возвращает новый объект std::string.

В выражении std::copy(stream.str().begin(), stream.str().end(),&buffer[0]); stream.str().begin() будет итератором на начало одной строки, а stream.str().end() будет итератором на конец уже совершенно другого объекта-строки.

Это тоже самое, если к примеру в алгоритм поиска в последовательности отправить начало одного вектора и конец другого

std::vector<int> a;
std::vector<int> b;
std::find(a.cbegin(), b.cend(), 0);

Следовательно решение - запомнить объект перед вызовом copy:

auto str = stream.str();
std::copy(str.begin(), str.end(), &buffer[0]); // можно buffer.data() вместо &buffer[0]
Answer 2

Поскольку stream.str() возвращает строку, а не ссылку - как вам уже пояснили, это разные строки.

Но можно воспользоваться rdbuf(), который позволяет работать прямо с буфером:

std::copy(stream.rdbuf()->str().begin(), stream.rdbuf()->str().end(),&buffer[0]);

Так можно обойтись без создания лишней строки.

READ ALSO
Перемещение видимой области QGraphicsView

Перемещение видимой области QGraphicsView

У меня есть класс на основе QGraphicsViewЯ хочу сделать так, чтобы по кликам на WASD видимая сцена перемещалась в соответствующую сторону

163
Чтение русских символов из файла - C++

Чтение русских символов из файла - C++

Не могу понять, в чем проблемаПри чтении русских символов через wifstream из файла в wstring все равно появляются не русские символы, а бред какой-то(где)

215
JAVA(intelliJ idea) проблемы с установкой JDBC?

JAVA(intelliJ idea) проблемы с установкой JDBC?

Развернул на localhost сервер + поставил базу postgreSQLпервая на 8080 вторая на 5432

186
Как заменить getState и getId(из Thread) при исп. Runnable?

Как заменить getState и getId(из Thread) при исп. Runnable?

Я создавал потоки испextends Thread, решил заменить его на Runnable

191