user9212993
user9212993

Reputation:

Is using new thread safe to instantiate a singleton in an implementation similar to Scott Meyer's singleton idiom?

I came over this question recently, and got doubts about the Instance() function implementation:

class Configuration
{
public:
    static Configuration* Instance() {
        static Configuration * myInstance = new Configuration();
        return myInstance;
    }

    int i;
    // delete copy and move constructors and assign operators
    Configuration(Configuration const&) = delete;             // Copy  construct
    Configuration(Configuration&&) = delete;                  // Move construct
    Configuration& operator=(Configuration const&) = delete;  // Copy assign
    Configuration& operator=(Configuration &&) = delete;      // Move assign

protected:
    Configuration() {

    }
    ~Configuration() {}

    // ...
}

Unfortunately the OP doesn't seem to be able to provide a MCVE that reproduces that read access violation they claim.

Here's an example of the working code, there's only a single thread involved though.

Upvotes: 0

Views: 119

Answers (2)

AdvSphere
AdvSphere

Reputation: 986

Just as FYI, wanted to add the below reference which explains when to use a pointer and when not: https://isocpp.org/wiki/faq/ctors#construct-on-first-use-v2

Basically using a pointer will not leak since the OS will reclaim memory once the process exists, this is likely the best approach in most of the cases. However if the singleton needs to close another resource, i.e. a file, in destructor, then that's a problem. In that case don't use the static local variable as pointer but just a static local object. Make sure that any other static objects that use this object in destructors are used in their constructors as well, to make sure when the program exists, calls their destructors in correct order.

Upvotes: 0

Edgar Rokjān
Edgar Rokjān

Reputation: 17483

Is using an instance pointer and new in that implementation still guaranteed to be thread safe (a race condition could be a potential reason for that error)?

Yes, it is thread safe.

From N4659:

9.7 Declaration statement [stmt.dcl]

Dynamic initialization of a block-scope variable with static storage duration (6.7.1) or thread storage duration (6.7.2) is performed the first time control passes through its declaration; such a variable is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control enters the declaration concurrently while the variable is being initialized, the concurrent execution shall wait for completion of the initialization. If control re-enters the declaration recursively while the variable is being initialized, the behavior is undefined.

As myInstance is a block-scope variable with a static storage duration which is dynamically initialized, the code is thread-safe even if multiple threads are involved.

Upvotes: 1

Related Questions