I’m writing a unit test for a class MyClass
with the following (mock) implementation.
namespace MyClassStubData {
std::string inClientId; // From constructor
}
MyClass::MyClass(const std::string& clientId)
{
MyClassStubData::inClientId = clientId;
}
The namespace contains variables that will be set by MyClass
‘s various methods, including the constructor defined above. I’m running into a very weird issue. This assignment to MyClassStubData::inClientId
CRASHES with the following Valgrind error:
(Note: the class isn’t actually MyClass
, I renamed it, so this error is slightly off)
==147== Memcheck, a memory error detector
==147== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==147== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==147== Command: ia32/test_runner --gtest_death_test_style=threadsafe --gtest_death_test_use_fork
==147==
==147== Invalid write of size 1
==147== at 0x5956A6D: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_assign(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==147== by 0x5956E18: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::operator=(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==147== by 0x164DF4: MyClass::MyClass(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (MyClass.cpp:18)
.... (omitted)
But if I change the code snippet like so, it works!
MyClass::MyClass(const std::string& clientId)
{
MyClassStubData::inClientId = "foo";
MyClassStubData::inClientId = clientId;
}
I don’t know what’s happening here. Why would the assignment trigger an “Invalid write” error? It’s like the namespace variable isn’t initialized yet, but std::string
is a class, not a primitive. Also, giving it an initial value in the namespace doesn’t resolve the issue.
Note that I was unable to reproduce this in a small application, so it’s possibly related to project details I didn’t want to share here.