SQLite: consecutive invocation of finalize
up vote
1
down vote
favorite
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.
c++ sqlite
add a comment |
up vote
1
down vote
favorite
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.
c++ sqlite
1
I don't think I understand this correctly. Are you trying to finalize the same statement multiple times? You should only finalize it once. According to the documentation ( sqlite.org/c3ref/finalize.html ), it is "a grievous error" to use a prepared statement after having finalized, and I would assume that also applies to further finalize calls.
– Blaze
Nov 20 at 10:26
In one particular case i have this two consecutive invocations of finalize. I also checked the documentation but thought that finalize would have any kind of protection. But now it seems to have some kind of undefined behaviour. That's why i created this question.
– Георги Няголов
Nov 20 at 10:53
2
Well, it looks like there's protection for calling it on a NULL pointer ("harmless no-op"). I don't think there's such protection for invalid pointers, though, and I think the pointer becomes invalid after finalizing the statement once. The documentation mentions " undefined and undesirable behavior such as segfaults and heap corruption" - perhaps that's why it works only sometimes. You could also try checking the return statement of the second finalize call to see if it returnsSQLITE_OK
.
– Blaze
Nov 20 at 11:01
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
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.
c++ sqlite
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.
c++ sqlite
c++ sqlite
asked Nov 20 at 10:21
Георги Няголов
184
184
1
I don't think I understand this correctly. Are you trying to finalize the same statement multiple times? You should only finalize it once. According to the documentation ( sqlite.org/c3ref/finalize.html ), it is "a grievous error" to use a prepared statement after having finalized, and I would assume that also applies to further finalize calls.
– Blaze
Nov 20 at 10:26
In one particular case i have this two consecutive invocations of finalize. I also checked the documentation but thought that finalize would have any kind of protection. But now it seems to have some kind of undefined behaviour. That's why i created this question.
– Георги Няголов
Nov 20 at 10:53
2
Well, it looks like there's protection for calling it on a NULL pointer ("harmless no-op"). I don't think there's such protection for invalid pointers, though, and I think the pointer becomes invalid after finalizing the statement once. The documentation mentions " undefined and undesirable behavior such as segfaults and heap corruption" - perhaps that's why it works only sometimes. You could also try checking the return statement of the second finalize call to see if it returnsSQLITE_OK
.
– Blaze
Nov 20 at 11:01
add a comment |
1
I don't think I understand this correctly. Are you trying to finalize the same statement multiple times? You should only finalize it once. According to the documentation ( sqlite.org/c3ref/finalize.html ), it is "a grievous error" to use a prepared statement after having finalized, and I would assume that also applies to further finalize calls.
– Blaze
Nov 20 at 10:26
In one particular case i have this two consecutive invocations of finalize. I also checked the documentation but thought that finalize would have any kind of protection. But now it seems to have some kind of undefined behaviour. That's why i created this question.
– Георги Няголов
Nov 20 at 10:53
2
Well, it looks like there's protection for calling it on a NULL pointer ("harmless no-op"). I don't think there's such protection for invalid pointers, though, and I think the pointer becomes invalid after finalizing the statement once. The documentation mentions " undefined and undesirable behavior such as segfaults and heap corruption" - perhaps that's why it works only sometimes. You could also try checking the return statement of the second finalize call to see if it returnsSQLITE_OK
.
– Blaze
Nov 20 at 11:01
1
1
I don't think I understand this correctly. Are you trying to finalize the same statement multiple times? You should only finalize it once. According to the documentation ( sqlite.org/c3ref/finalize.html ), it is "a grievous error" to use a prepared statement after having finalized, and I would assume that also applies to further finalize calls.
– Blaze
Nov 20 at 10:26
I don't think I understand this correctly. Are you trying to finalize the same statement multiple times? You should only finalize it once. According to the documentation ( sqlite.org/c3ref/finalize.html ), it is "a grievous error" to use a prepared statement after having finalized, and I would assume that also applies to further finalize calls.
– Blaze
Nov 20 at 10:26
In one particular case i have this two consecutive invocations of finalize. I also checked the documentation but thought that finalize would have any kind of protection. But now it seems to have some kind of undefined behaviour. That's why i created this question.
– Георги Няголов
Nov 20 at 10:53
In one particular case i have this two consecutive invocations of finalize. I also checked the documentation but thought that finalize would have any kind of protection. But now it seems to have some kind of undefined behaviour. That's why i created this question.
– Георги Няголов
Nov 20 at 10:53
2
2
Well, it looks like there's protection for calling it on a NULL pointer ("harmless no-op"). I don't think there's such protection for invalid pointers, though, and I think the pointer becomes invalid after finalizing the statement once. The documentation mentions " undefined and undesirable behavior such as segfaults and heap corruption" - perhaps that's why it works only sometimes. You could also try checking the return statement of the second finalize call to see if it returns
SQLITE_OK
.– Blaze
Nov 20 at 11:01
Well, it looks like there's protection for calling it on a NULL pointer ("harmless no-op"). I don't think there's such protection for invalid pointers, though, and I think the pointer becomes invalid after finalizing the statement once. The documentation mentions " undefined and undesirable behavior such as segfaults and heap corruption" - perhaps that's why it works only sometimes. You could also try checking the return statement of the second finalize call to see if it returns
SQLITE_OK
.– Blaze
Nov 20 at 11:01
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
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?"
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53390865%2fsqlite-consecutive-invocation-of-finalize%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
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?"
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
add a comment |
up vote
1
down vote
accepted
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?"
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
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?"
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?"
answered Nov 20 at 11:06
Lightness Races in Orbit
281k51453769
281k51453769
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
add a comment |
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
Thank you all for the answers. It is obvious that i will redesign the code in order to remove this consecutive invocation of finalize. The reason of the question was to understand the problem clearly, which was achieved. Thanks again.
– Георги Няголов
Nov 20 at 12:15
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53390865%2fsqlite-consecutive-invocation-of-finalize%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I don't think I understand this correctly. Are you trying to finalize the same statement multiple times? You should only finalize it once. According to the documentation ( sqlite.org/c3ref/finalize.html ), it is "a grievous error" to use a prepared statement after having finalized, and I would assume that also applies to further finalize calls.
– Blaze
Nov 20 at 10:26
In one particular case i have this two consecutive invocations of finalize. I also checked the documentation but thought that finalize would have any kind of protection. But now it seems to have some kind of undefined behaviour. That's why i created this question.
– Георги Няголов
Nov 20 at 10:53
2
Well, it looks like there's protection for calling it on a NULL pointer ("harmless no-op"). I don't think there's such protection for invalid pointers, though, and I think the pointer becomes invalid after finalizing the statement once. The documentation mentions " undefined and undesirable behavior such as segfaults and heap corruption" - perhaps that's why it works only sometimes. You could also try checking the return statement of the second finalize call to see if it returns
SQLITE_OK
.– Blaze
Nov 20 at 11:01