Visual Studio MSC++ 编译器崩溃

Posted

技术标签:

【中文标题】Visual Studio MSC++ 编译器崩溃【英文标题】:Visual Studio MSC++ compiler crash 【发布时间】:2014-02-15 05:34:40 【问题描述】:

我正在用 C++ 实现一个列表类,我在该类中添加了一些代码,每次构建编译器时似乎都会崩溃,如果我编写一个基本的“Hello World”,它就可以干净地编译。这是列表的源代码。如果有人可以解决这个问题,将不胜感激,这对我来说毫无意义,谢谢!

注意:该列表未完成,因此如果您发现错误和错误,请随时指出。

使用 Visual Studio 2013 Ultimate 平台工具集:v120

#ifndef _LIST_HPP_
#define _LIST_HPP_

#include <initializer_list>

template<typename ty_> 
class List final 
public:
    using value_type = ty_;

private:
    using uint32_t = unsigned;
    using init_list= std::initializer_list<value_type>;

    typedef struct _Node 
        _Node* _prevNode;
        _Node* _nextNode;
        value_type _value;
    ;

    _Node* _begin; //begin points to another Node [delimeter] for iterators
    _Node* _end;   //end points to another Node [delimeter] for iterators

    uint32_t _size; //hold the size of the current list

public:
    //Insert Enumerations
    enum Location 
        BEG,
        MID,
        END
    ;

    class Forward_Iterator;
    class Reverse_Iterator;
    class Iterator final : public Reverse_Iterator, public Forward_Iterator;

    //Constructors
    List();                        //Initialize the List with null's
    List(const List<value_type>&); //Copy constructor
    List(const init_list&);        //Pre-Allocate with values to the List

    ~List();

    //Methods
    auto push_back(const value_type&) -> void;  //push 1 value on the back
    auto push_back(const init_list&) -> void;   //push n values on the back

    auto pop_back() -> void;                    //remove 1 value from the back
    auto pop_back(const uint32_t&) -> void;     //remove n values from the back

    auto push_front(const value_type&) -> void; //push 1 value on the front
    auto push_front(const init_list&) -> void;  //push n values on the front

    auto pop_front() -> void;                   //remove 1 value from the front
    auto pop_front(const uint32_t&) -> void;    //remove n values from the front

    //insert various values in a specified location based on an enumeration
    auto emplace(const init_list&, const Location& = END) -> void;

    auto insert(const uint32_t&, const value_type&)->Iterator&; //insert 1 value return added address
    auto insert(const uint32_t&, const init_list&)->Iterator&;  //insert multiple values get the ending inserte address
    auto insert(const uint32_t&, const Iterator&)->Iterator&;   //Insert 1 Node and get the inserted address
    auto insert(const Iterator&, const Iterator&)->Iterator&;   //Insert 1 Node and get the inserted address

    auto erase(const Iterator&)->Iterator&;    //erase and element by Iterator address
    auto erase(const uint32_t&)->Iterator&;    //erase and element by poition in list

    auto find(Iterator&)->Iterator&;     //find an element by Iterator address
    auto find_first_of(const value_type&)->Iterator&;    //find the first of a specific value
    auto find_last_of(const value_type&)->Iterator&;     //find the last of a specific value

    auto empty() const -> bool;                  //check if empty

    auto size() const->uint32_t;                 //get the size

    auto begin()->Forward_Iterator&;             //beginning
    auto end()->Forward_Iterator&;           //ending

    auto cbegin() const->Forward_Iterator&;  //const beginning
    auto cend() const->Forward_Iterator&;        //const ending

    auto rbegin()->Reverse_Iterator&;            //reverse beginning
    auto rend()->Reverse_Iterator&;          //reverse ending

    auto crbegin() const->Reverse_Iterator&;     //const reverse beginning
    auto crend() const->Reverse_Iterator&;   //const reverse ending
;

#pragma region List_Constructors

//Returns: Nothing
//Purpose: Initializes the private data members.
template<typename ty_>
List<ty_>::List() 
    this->_begin = nullptr; 
    this->_end = nullptr; 
    this->_size = 0;


//Returns: Nothing
//Purpose: Initializes a new list with the data of another list.
template<typename ty_>
List<ty_>::List(const List<value_type>& CPY_LIST) 
    this->_begin = nullptr;
    this->_end = nullptr;
    this->_size = 0;
        _Node* currentNode = CPY_LIST._begin;
    while (currentNode && (currentNode != CPY_LIST._end->_nextNode))
        this->push_back(currentNode->_value);
        currentNode = currentNode->_nextNode;
    


//Returns: Nothing
//Purpose: Initialize n positions with specified values VIA initializer list.
template<typename ty_>
List<ty_>::List(const init_list& I_LIST) 
    this->_begin = nullptr;
    this->_end = nullptr;
    this->_size = 0;
    for (const auto& VAL : I_LIST)
        this->push_back(VAL);


#pragma endregion

#pragma region List_Destructor

template<typename ty_>
List<ty_>::~List() 
    if (this->_begin->_prevNode)
        delete this->_begin->_prevNode;
    _Node* current = this->_begin;
    while (current && (current != this->_begin->_nextNode))
        _Node* toDelete = current;
        current = current->_nextNode;
        delete toDelete;
    
    if (this->_end->_nextNode)
        delete this->_end->_nextNode;


#pragma endregion

#pragma region Push_Methods

//Returns: void
//Purpose: Adds a new value to the end of the list.
template<typename ty_>
auto List<ty_>::push_back(const value_type& VAL) -> void 
    if (!this->_begin)
        //create the beginning node.
        _Node* begNode = new _Node nullptr, this->_end, VAL ;
        begNode->_prevNode = new _Node nullptr, begNode, 0 ;
        this->_begin = begNode;
    
    else if (!this->_end)
        //create the ending node
        _Node* endNode = new _Node this->_begin, nullptr, VAL ;
        endNode->_nextNode = new _Node endNode, nullptr, 0 ;
        this->_end = endNode;
        this->_begin->_nextNode = this->_end;
    
    else 
        //extend the ending
        this->_end->_nextNode->_value = VAL;
        this->_end->_nextNode->_nextNode = new _Node this->_end->_nextNode, nullptr, 0 ;
        this->_end = this->_end->_nextNode;
    
    ++this->_size;


//Returns: void
//Purpose: Adds new values to the end of the list.
template<typename ty_>
auto List<ty_>::push_back(const init_list& I_LIST) -> void 
    for (const auto& VAL : I_LIST)
        this->push_back(VAL);


//Returns: void
//Purpose: Adds a new value to the beginning of the list.
template<typename ty_>
auto List<ty_>::push_front(const value_type& VAL) -> void 
    if (!this->_begin)
        //create the beginning node.
        _Node* begNode = new _Node nullptr, this->_end, VAL ;
        begNode->_prevNode = new _Node nullptr, begNode, 0 ;
        this->_begin = begNode;
    
    else if (!this->_end)
        //create the ending to be the previous beginning
        this->_begin->_nextNode = new _Node this->_begin, nullptr, this->_begin->_value ;
        this->_end = this->_begin->_nextNode;
        this->_end->_nextNode = new _Node this->_end, nullptr, 0 ;
        this->_begin->_value = VAL;
    
    else 
        //Extend the beginning
        this->_begin->_prevNode->_value = VAL;
        this->_begin->_prevNode->_prevNode = new _Node nullptr, this->_begin->_prevNode, 0 ;
        this->_begin = this->_begin->_prevNode;
    
    ++this->_size;


//Returns: void
//Purpose: Adds new values to the beginning of the list.
template<typename ty_>
auto List<ty_>::push_front(const init_list& I_LIST) -> void 
    for (const auto& VAL : I_LIST)
        this->push_front(VAL);


#pragma endregion

#pragma region Pop_Methods

//Returns: void
//Purpose: Erases 1 element from the end of the list
template<typename ty_>
auto List<ty_>::pop_back() -> void 



//Returns: void
//Purpose: Erases n elements from the end of the list
template<typename ty_>
auto List<ty_>::pop_back(const uint32_t& POP_COUNT) -> void 



//Returns: void
//Purpose: Erases 1 element from the beginning of the list
template<typename ty_>
auto List<ty_>::pop_front() -> void 



//Returns: void
//Purpose: Erases n element from the beginning of the list
template<typename ty_> 
auto List<ty_>::pop_front(const uint32_t& POP_COUNT) -> void 



#pragma endregion

#pragma region Insert_Methods

template<typename ty_> 
auto List<ty_>::emplace(const init_list& I_LIST, const Location& LOC) -> void 



#pragma endregion

//Returns: uint32_t or unsigned int
//Purpose: Get the current list's size.
template<typename ty_> 
auto List<ty_>::size() const -> uint32_t 
    return this->_size;


//Returns: Boolean
//Purpose: Checks whether the current list is empty.
template<typename ty_> 
auto List<ty_>::empty() const -> bool 
    return ((this->_size) ? (true) : (false));


#pragma region Positional_Methods

//template<typename ty_> auto List<ty_>::begin() -> Forward_Iterator& 
//  return Forward_Iterator(this->_begin->_prevNode);
//
//
//template<typename ty_> auto List<ty_>::cbegin() const -> Forward_Iterator& 
//  return Forward_Iterator(this->_begin->_prevNode);
//
//
//template<typename ty_> auto List<ty_>::end() -> Forward_Iterator& 
//  return Forward_Iterator(this->_end->_nextNode);
//
//
//template<typename ty_> auto List<ty_>::cend() const -> Forward_Iterator& 
//  return Forward_Iterator(this->_end->_nextNode);
//
//
//template<typename ty_> auto List<ty_>::rbegin() -> Reverse_Iterator& 
//  return Reverse_Iterator(this->_begin->_prevNode);
//
//
//template<typename ty_> auto List<ty_>::crbegin() const -> Reverse_Iterator& 
//  return Reverse_Iterator(this->_begin->_prevNode);
//
//
//template<typename ty_> auto List<ty_>::rend() -> Reverse_Iterator& 
//  return Reverse_Iterator(this->_end->_nextNode);
//
//
//template<typename ty_> auto List<ty_>::crend() const -> Reverse_Iterator& 
//  return Reverse_Iterator(this->_end->_nextNode);
//

#pragma endregion

#endif

【问题讨论】:

您首先定义了一堆保留名称(初始下划线后跟大写字母),这会导致未定义的行为。我无法想象任何习惯于 C++ 的人在任何情况下都会发现这些改进。 删除了所有的宏,它仍然做同样的事情,有什么想法吗? 【参考方案1】:

很难确定代码中的哪些问题让 VC++ 如此悲痛,但其中一些最明显的问题包括:

    使用_Node(首字母下划线后跟大写字母表示保留此名称)。 试图将Iterator 声明为派生自Forward_IteratorReverse_Iterator,而没有定义其中任何一个基类(您拥有的是声明,而不是定义)。 拥有一个实际上并未声明名称的 typedef

比如这样:

typedef struct _Node 
    _Node* _prevNode;
    _Node* _nextNode;
    value_type _value;
;

在这样的情况下使用typedef 无论如何都是C 的遗留物。你几乎肯定只想要:

struct _Node 
    _Node* _prevNode;
    _Node* _nextNode;
    value_type _value;
;

修复这些问题后,代码至少应该有更好的编译机会。

如果你也摆脱了无用的this-&gt; 噪音,它甚至可能开始看起来像真正的 C++,而不是 Java 的扭曲版本或其他东西。

为了进一步了解这个概念,您还应该开始使用成员初始化列表,例如替换:

template<typename ty_>
List<ty_>::List() 
    _begin = nullptr; 
    _end = nullptr; 
    _size = 0;

...与:

template<typename ty_>
List<ty_>::List() : _begin(nullptr), _end(nullptr), _size(0)

【讨论】:

我正在拿出一些东西来尝试推断问题,它似乎是迭代器,所以我将以不同的方式实现它们,非常感谢您的努力和建议我会记住它们。

以上是关于Visual Studio MSC++ 编译器崩溃的主要内容,如果未能解决你的问题,请参考以下文章

将新的 MS C++ 编译器与旧的 Visual Studio 一起使用

在 VS 2012 (C++) 中编译 Visual Studio 2010 项目:错误 LNK2038:检测到“_MSC_VER”不匹配:值“1600”与值“1700”不匹配

如何解决 Visual Studio 编译器崩溃

使用 Visual Studio 编译 hunspell

为啥 Roslyn 在尝试重写此 lambda 时会崩溃? (Visual Studio 2015 更新 1)

Visual Studio 控制台程序在 control-c 后崩溃