Странное поведение при использовании статических встроенных членов C ++ 17 в Visual Studio - PullRequest
0 голосов
/ 15 октября 2018

Вчера я задал вопрос об этой проблеме, но я не смог дать MVCE.Мне удалось воспроизвести это с помощью простой программы.Проблема заключается в использовании std :: list в качестве статического встроенного объявления в классе.Microsoft Visual Studio поддерживает эту новую функцию C ++ 17.По состоянию на март у него были некоторые ошибки, но, насколько я знаю, они были исправлены с тех пор.Вот инструкции, как я могу получить эту проблему, это происходит в режиме отладки.

В main.cpp

#include <iostream>
#include "header1.h"

int main()
{
    return 0;
}

В header1.h:

#include <list>

struct Boo
{
    static inline std::list<int> mylist;
};

В anotherCPP.cpp

#include "Header1.h"

Когда программа выходит из main (), она уничтожает все статические объекты и выдает исключение.

Если это не дает сбоя, возможно, в вашей системе компилятор / компоновщик оптимизировал некоторый код, поэтому вы можете попробовать сделать main.cpp и anotherCPP.cpp doчто-то.В anotherCPP.cpp :

#include <iostream>
#include "Header1.h"

void aFunction()
{
    std::cout << Boo::mylist.size();
}

и сделать main.cpp:

#include <iostream>
#include "Header1.h"

void aFunction();

int main()
{
    std::cout << Boo::mylist.size();
    afunction();

    return 0;
}

Когда программа завершает работу, я получаю исключение, когда std :: listочищается.Вот код отладки Visual Studio, в котором происходит сбой:

for (_Nodeptr _Pnext; _Pnode != this->_Myhead(); _Pnode = _Pnext)
{   // delete an element
    _Pnext = _Pnode->_Next; // Here: Exception thrown: 
                            // read access violation.
                            // _Pnode was 0xFFFFFFFFFFFFFFFF.

    this->_Freenode(_Pnode);
}

Это происходит только в том случае, если я объявил статический встроенный myd std :: list в классе.Если я объявлю его как static std :: list mylist в моем классе, а затем определю его отдельно в одном .cpp как std :: list Boo :: mylist; работает нормально.Эта проблема возникает, когда я объявляю статическую строку std :: list и включаю заголовок для класса в два файла .cpp.

В моем проекте я прошел сверху цикл очистки std :: list сверху,Я принял к сведению адрес указателя "this".Я прошел через цикл, так как он освободил узлы в моем списке.Затем он вернулся, чтобы освободить другие std :: lists, в том числе и в std :: unordered_map (так как они также используют std :: lists, судя по всему).Наконец, когда генерируется исключение доступа для чтения и _Pnode является недопустимым адресом указателя, я заметил, что адрес указателя "this" совпадает с адресом указателя "this" при очистке std :: list mylist , который заставляет меня думать, что он пытается удалить его дважды, и, возможно, почему это происходит сбой.

Я надеюсь, что кто-то может воспроизвести это, я не уверен, что это, если это ошибка или что-то я делаю неправильно.Также это происходит для меня в 32- и 64-разрядных системах, но только в режиме отладки, поскольку предоставленный мной цикл освобождения узла находится под макросом:

#if _ITERATOR_DEBUG_LEVEL == 2

1 Ответ

0 голосов
/ 15 октября 2018

Эта проблема была зарегистрирована как ошибка здесь под заголовком «Несколько инициализаций встроенного статического члена данных в режиме отладки».

Это было найдено в Visual Studio 2017 версии 15.7.

Команда компиляторов VS приняла это и исправила проблему в следующем выпуске.

...