Russian Qt Forum

Qt => Общие вопросы => Тема начата: FAngel от Сентябрь 17, 2010, 17:05



Название: Инициализация статической переменной с либе
Отправлено: FAngel от Сентябрь 17, 2010, 17:05
Имеется солюшен состоящий их 3-х проектов - common, core, core_test
common - статическая либа
core - динамическая либа.
core_test - приложение.

В common есть класс вида

class Singleton
{
public:
    static Singleton * getInStance();
private:
    static QMutex * mutex;
    static Singleton * instance;
}

библиотека core зависит от common и дергает в своих недрах getInstance

В *.cpp написано следующее.

QMutex * Singleton::mutex = new QMutex();

Singleton * Singleton::getInstance()
{
    mutex->lock();
    // magic
    mutex->unlock();

}

Собственно проблема. При загрузке core дергает этот getInstance() и на инструкции mutex->lock() падает по разименованию нулевого указателя. Ставил бряки на new, на конструктор QMutex. Ни то ни другое не вызывается.

Вопрос, почему не вызывается и как переписать что бы происходила инициализация.


Название: Re: Инициализация статической переменной с либе
Отправлено: kramer3d от Сентябрь 18, 2010, 10:16
Если я правильно понимаю, еще где-то в cpp у вас должна быть строка
Код
C++ (Qt)
Singleton* Singleton::instance = Singleton::getInstance();
 
т.е. в результате типичная ошибка статической инициализации. Статические члены инициализируются в произвольном порядке, и у вас instance инициализируется перед mutex. Погуглите про синглтон Майерса и про Double Lock Checking, эта тема довольно подробно раскрыта у Александреску, например.

UPD: Самый простой способ - это заменить статический член mutex статической же функцией, возвращающей референс на этот мьютекс:
Код
C++ (Qt)
private:
static QMutex& mutex() {
   static QMutex _mutex;
   return _mutex;
}
 


Название: Re: Инициализация статической переменной с либе
Отправлено: FAngel от Сентябрь 21, 2010, 11:15
Спасибо, уже разобрался. После того как написал сообразил.
 В итоге отказался от того, что бы dll сама себя инициализировала, а вызываю метод инициализации из приложения.