#251 Overlapping memcpy in string::assign


string::assign(const char* s, size_t n) uses memcpy to copy new data into its buffer. This is invalid when the first argument points inside the string buffer. Example:

#include <string>

std::string s = "adasdsadasdsadsadasdasdsadsad";

void f(void) {
volatile int n = s.size();
s.assign((char*)s.data() + 0x10, n - 0x10);

int main(void) {
volatile int z = s.size();
return 0;

AFAIU, C++ standard allows such use.
Build this with g++ -O0 -g -fno-builtin and run under Valgrind.

Source and destination overlap in memcpy(0x5e240c0, 0x5e240d0, 42)
at 0x4C2C774: memcpy
by 0x4018C7: stlp_std::__char_traits_base<char, int>::copy(char*, char const*, unsigned long)
by 0x4014E1: stlp_std::basic_string<char, stlp_std::char_traits<char>, stlp_std::allocator<char> >::_M_assign(char const*, char const*)
by 0x4012DF: stlp_std::basic_string<char, stlp_std::char_traits<char>, stlp_std::allocator<char> >::assign(char const*, unsigned long)
by 0x400E20: f()
by 0x400E43: main

Tested with STLport-5.2.1.


  • Petr Ovtchenkov

    Petr Ovtchenkov - 2011-06-21
    • assigned_to: nobody --> complement
  • Comment has been marked as spam. 

    You can see all pending comments posted by this user  here

    Anonymous - 2011-06-21

    Why not? The closest I found in the standard is


    6 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated
    by the following uses of that basic_string object:
    — as an argument to any standard library function taking a reference to non-const basic_string as an
    — Calling non-const member functions, except operator[], at, front, back, begin, rbegin, end, and

    AFAIU this means that element references become invalid after calls to string methods (other then the listed ones). Passing it as an argument to any string methods, including mutating methods, is valid, otherwise a lot of common usages will be incorrect. basic_string::assign

    basic_string& assign(const charT* s, size_type n);
    8 Requires: s points to an array of at least n elements of charT.
    9 Throws: length_error if n > max_size().
    10 Effects: Replaces the string controlled by *this with a string of length n whose elements are a copy
    of those pointed to by s.
    11 Returns: *this.

    Nothing here.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks