Reputation: 43
I have a function which aims to delete a concrete row from a SQLite database by an UID identifier.
The sequence is the following:
1. Create select query to check if the row exists
2. Prepare the query
3. Bind the row UID
4. Step
5. Finalize
If the row exist
{
6. Create delete query
7. Prepare it
8. Bind the UID
9. Step
10. Finalize
11. Finalize
}
As you can see first it checks if the row exist in order to notify the caller if the required UID is wrong, than it create new delete query.
The program works as expected in ~14/15 test cases. In the cases where the program is crashing it crashes to the last finalize invocation (11th point). I've checked all the data and it seems that everything is valid.
The question is what is the expected behaviour of consecutive invocation of finalize function. I tried to set 5 invocations of finalize one after another but the behaviour is the same.
Upvotes: 1
Views: 401
Reputation: 385395
Though the documentation doesn't feel the need to state this explicitly, it's fairly obvious that what you're doing is "undefined behaviour" (within the scope of the library).
Much like delete
ing dynamically allocated memory, you are supposed to finalize once. Not twice, not five times, but once. After you've finalized a prepared statement, it has been "deleted" and no longer exists. Any further operations on that prepared statement constitutes what the documentation calls "a grivous error" (if we presume that a superfluous call to finalize
constitutes "use"; and why would we not?).
Fortunately there is no reason ever to want to do this. So, quite simply, don't! If your design is such that you've lost control of your code flow and, at the point of finalize
, for some reason have insufficient information about your program's context to know whether the prepared statement has already been finalized, that's fine: much like we do with pointers, you can set it to nullptr
so that subsequent calls are no-ops. But if you need to do this, you really should also revisit your design.
Why did it appear to work for you? Pure chance, much like with any other undefined behaviours:
Any use of a prepared statement after it has been finalized can result in undefined and undesirable behavior such as segfaults and heap corruption.
See also: "Why can't I close my car door twice without opening it?" and "Why can't I shave my imaginary beard?"
Upvotes: 1