new возвращает NULL при инициализации статической глобальной переменной в windows? - PullRequest
1 голос
/ 12 февраля 2010

Я работаю над интеграцией rLog с нашей базой кода и замечаю проблему в Windows, которой у меня нет в linux. В заголовочном файле у меня есть статическая переменная, которая дает мне «подробный» канал ведения журнала (в основном один из отладочных), определенный таким образом:

static RLogChannel *rlog_verbose = DEF_CHANNEL("verbose", Log_Debug);

В Linux нет проблем с этим, но в Windows я получаю сообщение об ошибке, как только приложение запускается.

Я отследил это до этой строки в библиотеке rLog:

RLogChannel *rlog::GetComponentChannel(const char *component, const char* path, LogLevel levl) {
...
if(!gRootChannel)
    gRootChannel = new RLogChannel( "", level );
...
}

Проблема в том, что при вызове new возвращается указатель NULL, который не проверяется и программа быстро падает, когда к ней обращаются. Существуют ли правила, связанные с распределением памяти в глобальном контексте в Windows, от которых я не отказался?

Редактировать: Я почти уверен, что это должно быть связано с порядком инициализации статических объектов. Я хотел быть уверен, что я не пропустил что-то очевидное в отношении распределения памяти в Windows. Спасибо всем!

Ответы [ 3 ]

4 голосов
/ 12 февраля 2010

Вы уверены, что он возвращает ноль. Это может быть весь статический инициализатор. Порядок статических вызовов инициализатора не определяется из файла в файл. Если у вас есть статический код, который использует rlog_verbose, тогда gRootCHannel вполне может иметь значение NULL просто потому, что инициализатор еще не был вызван.

1 голос
/ 12 февраля 2010

new не возвращает NULL. он выдает исключение std::bad_alloc, если это не удается. Это происходит, даже если происходит статическая инициализация данных, которая фактически вызывается в CRT-функции точки входа, которая позже вызывает main().

Возможно, вы видите NULL, поскольку new никогда не вызывался. Чтобы убедиться, что он действительно вызывается, вы можете просто установить точку останова на статическую инициализацию и посмотреть, когда это произойдет.

0 голосов
/ 12 февраля 2010

new не возвращает ноль. Поэтому ваша проблема должна заключаться в том, что вы используете rlog_verbose до того, как ваш статический инициализатор выполнится. Возможно, ваш статический инициализатор никогда не выполняется . (это было бы проблемой со связью)

Вам нужно запустить отладчик и установить разрыв на вашем статическом инициализаторе, и на main, и на строке кода, которая дает сбой, и просто посмотреть, что происходит. Если вы переступите через аварию, это сработает? происходит ли авария до main?

...