пятница, 16 августа 2013 г.

[prog.c++] Перезаписать содержимое std::string посредством memcpy или чего-то в этом роде

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

Вот, например, почему-то у меня отложилось в мозгах, что стандарт C++03 не гарантировал что std::string хранит свое содержимое внутри себя как непрерывную последовательность байт. Т.е. грубо говоря, не следовало перезаписывать содержимое строки, например, таким образом: memcpy(&s[0],some_data,s.size()), где s -- это экземпляр std::string (достаточной емкости).

Обоснованием этого ограничения для меня было услышанное где-то когда-то предположение, что за стандартизированным интерфейсом basic_string может скрываться совершенно нетривиальная реализация, которая не хранит содержимое строки в виде непрерывной последовательности символов (например, используя ROPE-структуры). И что вроде как в природе существуют реализации STL, в которых basic_string как раз на основе ROPE и построены.

Но, насколько я могу судить, в C++11 жестко зафиксировали требование, что basic_string должно хранить свое содержимое в виде одной непрерывной последовательности:

The elements of a basic_string are stored contiguously, that is, for a basic_string s, &*(s.begin() + n) == &*s.begin() + n for any n in [0, s.size()), or, equivalently, a pointer to s[0] can be passed to functions that expect a pointer to the first element of a CharT[] array.

А это означает, что теперь можно смело перезаписывать содержимое std::string через memcpy, если предварительно позаботится о достаточном размере std::string. Ну или как в моем случае, использовать внутренний буфер std::string для приемника во время чтения содержимого строки из бинарного потока (без необходимости использования промежуточных буферов, как в случае с C++03).

Что не может не радовать. В конце-концов, C++ язык для околосистемного программирования и четкая фиксация того, как стандартные классы должны хранить свое содержимое (в частности для basic_string и vector) сильно облегчает работу с битиками и байтиками.

Комментариев нет: