我有一个旨在通过UID标识符从SQLite数据库中删除具体行的功能。
顺序如下:
1.创建选择查询以检查该行是否存在
2.准备查询
3.绑定行UID
4.步骤
5.完成
如果该行存在
{
6.创建删除查询
7.准备
8.绑定UID
9.步骤
10.完成
11.完成
}
首先您会看到,它会检查行是否存在,以便在必要的UID错误的情况下通知调用方,然后创建新的删除查询。
程序在〜14/15测试用例中按预期工作。在程序崩溃的情况下,它崩溃到最后一次完成调用(第11点)。我检查了所有数据,似乎一切都有效。
问题是finalize函数连续调用的预期行为是什么?我尝试设置5个调用,一个接一个地完成,但是行为是相同的。
答案 0 :(得分:1)
尽管the documentation不需要明确声明这一点,但很明显,您所做的是“未定义的行为”(在库的范围内)。
就像delete
动态分配内存一样,您应该确定一次 。不是两次,不是五次,而是一次。完成准备好的语句后,该语句已被“删除”并且不再存在。在该准备好的语句上进行的任何进一步操作都构成了文档所说的“小错误”(如果我们假定对finalize
的多余调用就构成了“使用”;为什么我们不这样做?)。
幸运的是,没有理由。所以,很简单,不要!如果您的设计使您无法控制代码流,并且在finalize
时由于某种原因而没有足够的有关程序上下文的信息来知道准备好的语句是否已经完成,那很好:非常类似于我们对指针的处理,您可以将其设置为nullptr
,以便后续调用成为无操作。但是,如果您需要执行此操作,则还应该重新访问设计。
为什么它似乎对您有用?纯粹的机会,就像其他任何不确定的行为一样:
在结束后使用任何准备好的语句都可能导致未定义的不良行为,例如段错误和堆损坏。
另请参阅:“为什么我不能不打开车门就关两次?” 和“为什么我不能剃掉假想的胡须?” < / p>