c++ - STL列表异常

标签 c++ exception list stl

我试图在 C++ 中使用 STL 列表,但遇到了一个我无法理解的奇怪异常。

该列表定义为list<ASTNode*> m_stats;ASTNode*是一个类。当我尝试通过调用添加元素时

ASTNode *node = new ASTNode();
m_stats.push_back(node);

它抛出以下异常:

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000004
0x91c20fe7 in std::_List_node_base::hook()

我尝试使用 gdb 进行调试并检查插入的值,它是否不为空,并且它正是应该的样子..

回溯是:

#0  0x91c20fe7 in std::_List_node_base::hook ()
#1  0x0000a9fb in std::list<ASTNode*, std::allocator<ASTNode*> >::_M_insert (this=0x180344, __position={_M_node = 0x0}, __x=@0xbffff094) at stl_list.h:1152
#2  0x0000aa27 in std::list<ASTNode*, std::allocator<ASTNode*> >::push_front (this=0x180344, __x=@0xbffff094) at stl_list.h:743
#3  0x0000aa45 in ASTStatements::addStatement (this=0x180340, stat=0x180410) at ast.h:277

我错过了什么吗?

编辑:添加类源

class ASTStatements : public ASTNode
{
list<ASTNode*> m_stats;

public:
    ASTStatements() {}

    ASTStatements(list<ASTNode*> stats)
    {
        std::copy(stats.begin(), stats.end(), m_stats.begin());
    }

    ASTStatements(const ASTStatements &other)
    {
        std::copy(other.m_stats.begin(), other.m_stats.end(), m_stats.begin());
    }

    ASTStatements &operator= (const ASTStatements &other)
    {
        if (&other != this)
        {
            std::copy(other.m_stats.begin(), other.m_stats.end(), m_stats.begin());
        }
    }

    ASTStatements *clone()
    {
            return new ASTStatements(*this);
        }

        u8 type()
        {
            return 0;
        }

        const char *generateASM()
        {
            list<ASTNode*>::iterator it = m_stats.begin();

            while (it != m_stats.end())
            {
                ((ASTNode*)*it)->generateASM();
                ++it;
            }
        }

        void addStatement(ASTNode *stat)
        {
            m_stats.push_front(stat);
        }

        u8 typeCheck()
        {
            return 0;
        }
};

我在野牛语法文件中使用它来处理多个语句(没有找到更好的方法来处理非终端中的通用项目列表):

statements:
    statement { if ($$ == null) $$ = new ASTStatements(); ((ASTStatements*)$$)->addStatement($1); } statements { $$->generateASM(); }

;

提前致谢

最佳答案

你的构造函数和赋值语句是错误的。当您调用std::copy时,目标迭代器必须已经有足够的空间来容纳您复制到其中的所有内容。该列表不会自行增长。您收到的错误消息表明您正在覆盖一些内存,而当您尝试复制到不够大的列表中时,这可能正是发生的情况。 (正式而言,该行为未定义。)

您可以使用std::back_insert_iterator ,它是一个迭代器适配器,它将项目附加到底层容器而不是覆盖当前位置。使用 std::back_inserter 创建一个来自 <algorithm> 的辅助函数标题:

std::copy(stats.begin(), stats.end(), std::back_inserter(m_stats));

不过,更好的是跳过所有复制,让列表自己的构造函数和赋值运算符为您处理它,因为它们的设计目的是:

ASTStatements(list<ASTNode*> stats)
  : m_stats(stats)
{ }

ASTStatements& operator=(const ASTStatements& other)
{
  m_stats = other.m_stats;
}

关于c++ - STL列表异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1653375/

相关文章:

Java : Catch exception in different thread

java - 捕获所有类型的异常编程 Android

python - 在 python 中构建矩阵

python - 如果大小增加,为什么 python 列表的位置没有改变?

C++ 指针 - visual studio 抛出异常

c++ - C++ 中的通用参数检查器

c++ - std::codecvt_utf8 方面的问题

java - 运行java程序出错: java. lang.NoClassDefFoundError

list - 在 Sharepoint 联系人列表中制作可点击的电话超链接

c++ - If 语句仅在调试 cout 行之前通过(C 中的多线程)