【发布时间】:2021-12-30 07:44:37
【问题描述】:
我正在尝试调试类的成员函数中指针的值意外更改为0x1 的问题。我意识到这可能是一个常见问题,并且由于堆栈上的某些变化。但是我没有足够的经验来确切地知道原因是什么以及我应该在设计中进行哪些更改来修复它。任何好的 cmets 或建议将不胜感激。
当我尝试查找键为 mlir::Operation* 的另一个容器(在不同的函数中)时,它将失败,因为指针的地址已更改。
我有一个名为 Schedule 的课程,看起来像这样。
成员函数next_schedulable_operation()如下所示:
std::cout << "The pointer value is " << *op_itr << std::endl;
candidates_.erase(op_itr);
std::cout << "The pointer value is " << *op_itr << std::endl;
schedule_operation(*op_itr);
std::cout << "The pointer value is " << *op_itr << std::endl;
schedulable_op_ = *op_itr;
std::cout << "The pointer value is " << *op_itr << std::endl;
}
}
}
我得到的输出是:
The pointer value is 0x555555695650
The pointer value is 0x555555695650
The pointer value is 0x1
当我省略最后一个 cout 语句时,它不会改变值,但我认为这只是巧合。
cmets 之后的变化:
【问题讨论】:
-
candidates_.erase(op_itr)之后,op_oitr变得无效(原因应该很明显 - 它曾经引用的元素不再在容器中,因此迭代器没有可引用的内容),并且随后的*op_itr表现出未定义的行为。 -
我怀疑您将
op_itr视为一种指向mlir::Operation*的指针,它在从列表中删除后一直指向相同的mlir::Operation*,但这是不是它是如何工作的。 -
您有时可以通过编译器警告、启用标准库的调试检查以及在编译时启用编译器的地址清理程序或内存清理程序来捕获可疑的内存错误。
-
谢谢。我理解您关于在从容器中删除元素后使迭代器无效的观点。我已经根据 cmets 修改了代码并将其放在原始问题的末尾。我可以创建一个 l 局部变量 mlir::Operation* op,然后将其分配给类成员变量 schedulable_op_ 吗?