c++ - Is it safe to use the Structure dereference(->) operator on the result of std::atomic::load -


whilst trying work std atomic pointer, ran following. this:

std::atomic<std::string*> mystring; // <do fancy stuff string... on other threads>  //a can this? mystring.load()->size()  //b can this? char myfifthchar = *(mystring.load()->c_str() + 5);  //c can this? char mychararray[255]; strcpy(mychararray, mystring.load()->c_str()); 

i'm pretty sure c illegal because mystring might deleted in meantime.

however i'm unsure , b. suppose illegal since pointer might deferenced whilst performing read operation.

however if case, how can ever read atomic pointer might deleted. since load 1 step, , reading of data 1 step.

it has been mentioned approach risky business. here may want consider instead: use std::shared_ptr<const std::string> immutable values, , shared_ptr atomic_load , atomic_store. std::shared_ptr ensure not access dangling pointer, while immutability (string not change after construction) guarantee accesses string thread-safe, const methods defined standard thread-safe.

edit: requested explanation of mean "risky business": if use std::atomic<std::string *>, it's easy accidentally introduce race conditions, e.g.

// data std::atomic<std::string *> str(new std::string("foo"));  // thread 1 std::cout << *str.load();  // thread 2 *str.load() = "bar"; // race condition read access in thread 1  // thread 2 (another attempt using immutable instances) auto newstr = new std::string("bar"); auto oldstr = str.exchange(newstr); delete oldstr;  /* race condition read access in thread 1                    because thread 1 may have performed load() before                    exchange became visible it, , may not                    finished using old object. */ 

note has nothing operator <<, calling size() on string in thread 1 lead race condition.

in practice, 1 may see "fixes" adding sleep before delete in update immutable strings, thread 1 has enough time finish business old pointer. although may work most of time in particular implementation, not introduce true ordering (a happens-before relation, in c++ standardese) , therefore not correct rsp. portable solution.


Comments