2009-10-31 30 views
2

我试图在C++中使用STL列表,并且遇到了一个我无法理解的奇怪异常。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和插入检测值进行调试,是不是null,它到底是什么它应该是..

回溯是:

#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}, [email protected]) at stl_list.h:1152 
#2 0x0000aa27 in std::list<ASTNode*, std::allocator<ASTNode*> >::push_front (this=0x180344, [email protected]) 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(); } 

;

在此先感谢

+1

问题不在于您发布的任何代码行中。显然,你的'list'在此之前已经被破坏了。 – 2009-10-31 04:13:27

+0

堆栈跟踪与发布的源代码不一致(push_back vs push_front等) – 2009-10-31 04:20:28

+1

您的程序没有抛出异常,而是您的操作系统正在使您的程序摆脱其带有分段错误的痛苦。 – 2009-10-31 05:29:37

回答

4

你的构造函数和赋值语句是错误的。当您拨打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; 
} 
+0

'ASTStatements(列表统计)' - 我不认为你想通过这样的列表每个复制。 'ASTStatements(const list &stats)''?而且,实际上,这个习惯用法是传递迭代器并将它们作为模板参数传递:'template ASTStatements(It begin,It end):m_stats(begin,end){}'。遵循常见的习语有其优点。 – sbi 2009-10-31 05:53:42

0

有最有可能的是你做了你的列表,您张贴的代码行之前发生。我建议看看所有的地方m_stats被使用,并仔细检查你的使用。你可以在这里发布m_stats的用法,我们可以尝试帮助你更多。