﻿# V1036\. Potentially unsafe double\-checked locking\.

Анализатор обнаружил потенциальную ошибку, связанную с небезопасным использованием паттерна "блокировки с двойной проверкой" \(double checked locking\)\. Блокировка с двойной проверкой \- это паттерн, предназначенный для уменьшения накладных расходов получения блокировки\. Сначала проверяется условие блокировки без синхронизации\. И только если условие выполняется, поток попытается получить блокировку\. Таким образом, блокировка будет выполнена только если она действительно была необходима\.

Рассмотрим пример с ошибкой:

```cpp
static std::mutex mtx;
class TestClass
{
public:
  void Initialize()
  {
    if (!initialized) 
    {
      std::lock_guard lock(mtx);
      if (!initialized) // <=
      {
        resource = new SomeType();
        initialized = true;
      }
    }
  }
  /* .... */

  private:
    bool initialized = false;
    SomeType *resource = nullptr;
  };
}
```

В этом примере, оптимизация компилятором порядка назначений переменных 'resource' и 'initialized' может привести к ошибке\. Т\.е\. в начале переменной 'initialized' будет присвоено значение 'true', а уже потом будет выделена память под объект типа 'SomeType' и проинициализирована переменная 'resource'\.

Такая перестановка может привести к ошибке при доступе к объекту из параллельного потока\. Получается, что переменная 'resource' будет еще не проинициализирована, а флаг 'intialized' уже будет выставлен в 'true'\.

Одна из опасностей таких ошибок состоит в том, что часто кажется, будто программа работает корректно\. Это происходит из\-за того, что рассмотренная ситуация будет возникать не очень часто, в зависимости от архитектуры используемого процессора\.

**Дополнительные ссылки:**

1. Scott Meyers and Andrei Alexandrescu\. [C\+\+ and the Perils of Double\-Checked Locking](https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf)\.
1. Stack Overflow\. [What the correct way when use Double\-Checked Locking with memory barrier in c\+\+?](https://stackoverflow.com/questions/52981057/what-the-correct-way-when-use-double-checked-locking-with-memory-barrier-in-c)
1. [Double\-Checked Locking is Fixed In C\+\+11](https://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/)\.