Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do std containers always throw exceptions in a multi-threaded environment?

Do containers like std::vector && friends (I'm actually using a QList) throw a catchable exception or is it undefined behavior if one thread tries to write to the container when another thread is reading from it:

std::vector<std::string> stuff;

Non-critical task (e.g. spell check) in another thread:

try {
    for (std::string& s : stuff) {
        //do stuff with s
    }
} catch (...) {  // Handle all exceptions
    //bail out of task
}

Main thread:

stuff.erase(std::remove(someIterator), stuff.end()); 

So you can see there would be a scenario here where it could have an invalidated iterator and an exception will be thrown in the read thread - which would be caught and just bail out of the task.

But that is just one scenario - can I rely on catchable exceptions to be thrown from these containers so that I don't need to protect the vectors or strings with a mutex? Or will there be some instances where it could dereference a nullptr (or something) and cause a SEH exception - i.e. something I can't catch and continue. I think the answer is that it's probably implementation dependent, and will most likely result in undefined behavior, but I thought I'd ask the question.

like image 770
gremwell Avatar asked Jun 29 '26 22:06

gremwell


2 Answers

Generally speaking, you can't count on access to an invalidated iterator throwing any sort of exception. The result is Undefined Behavior: the call could throw, it could crash, it could seem to work for years and then bite you later, it could break something unrelated elsewhere in your program.

The Standard forbids this sort of thing on the objects and functions of the standard library:

17.6.4.10/1:

The behavior of a program is undefined if calls to standard library functions from different threads may introduce a data race. The conditions under which this may occur are specified in 17.6.5.9.

17.6.5.9/6:

Operations on iterators obtained by calling a standard library container or string member function may access the underlying container, but shall not modify it. [ Note: In particular, container operations that invalidate iterators conflict with operations on iterators associated with that container. --end note ]

Most Qt functions are similarly not thread-safe.

If you need to share data between threads, protect yourself from data races. Don't count on a library to do it for you unless the documentation says it does.

like image 153
aschepler Avatar answered Jul 02 '26 11:07

aschepler


Using invalidated iterator is undefined behavior in its own right. It does not throw exception as you seem to think. So your idea (unless I misunderstood it) would not fly even with mutexing.

Data races accessing the same std:: object are also source of undefined behavior.

like image 22
Balog Pal Avatar answered Jul 02 '26 12:07

Balog Pal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!