segmentation fault with string and char*

Oct 8, 2019 at 5:43pm
hello
I'm trying to use SQLite in C++, but Im having some trouble.
I want to use the following SQLite statement, but it gives me a segmentation fault in the second line

1
2
int n = 10;
std::string str = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%q')", n);


with this error:
In sqlite3_str_vappendf () (/usr/lib/x86_64-linux-gnu/libsqlite3.so.0)
#3  0x0000555555557a1a in App::save (this=0x7fffffffd610, filename="001.db") at /home/diego/test_app.cpp:70


/home/diego/test_app.cpp:70:2371:beg:0x555555557a1a
At /home/diego/test_app.cpp:70


I believe sqlite3_mprintf returns a char*.
for some reason, if I substitute '%q' for 10, it works.

any idea on how to fix it?

thanks in advance!
Oct 8, 2019 at 6:15pm
does it work with %Q instead of '%q' ? (remove quotes too, just flat %Q)
not real familiar with this library, any chance it wanted &n instead of n here?
Last edited on Oct 8, 2019 at 6:17pm
Oct 8, 2019 at 6:36pm
Read the man page.
https://www.sqlite.org/c3ref/mprintf.html

The sqlite3_mprintf() and sqlite3_vmprintf() routines write their results into memory obtained from sqlite3_malloc64(). The strings returned by these two routines should be released by sqlite3_free(). Both routines return a NULL pointer if sqlite3_malloc64() is unable to allocate enough memory to hold the resulting string.


You can't just point at it, because that's a memory leak waiting to happen.

1
2
3
4
5
char *p = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%q')", n);
if ( p ) {
    std::string str(p);  // this ctor will make another copy
    sqlite3_free(p);
}


> for some reason, if I substitute '%q' for 10, it works.
Don't confuse "works" with "failed to crash because you did something wrong".
Bugs can lurk in the shadows for ages, all the time making you believe you're golden - until it actually crashes.



Oct 8, 2019 at 6:37pm
https://www.sqlite.org/printf.html#percentq
The argument is a zero-terminated string.

But 'n' is int.

Does
 
std::string str = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%d')", n);
work?
Oct 8, 2019 at 6:40pm
Yeah, that too :)
Oct 8, 2019 at 6:50pm
does it work with %Q instead of '%q' ? (remove quotes too, just flat %Q)
not real familiar with this library, any chance it wanted &n instead of n here?

actually had tried all these combinations before, and had no success :P

1
2
3
4
5
char *p = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%q')", n);
if ( p ) {
    std::string str(p);  // this ctor will make another copy
    sqlite3_free(p);
}

well, it still has the same segmentation fault...

Does
 
std::string str = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%d')", n);

work?

YES, and I feel so stupid now I want to put my head in a hole on the ground. I was sure it had something to do with conversion from char* to string i didn't notice that.

thanks for the help everybody!
Last edited on Oct 8, 2019 at 6:51pm
Oct 8, 2019 at 6:59pm
do you need std::string here for anything?
Just consume it as a char* if not, and then delete the memory.
the copy seems to be a copy for the sake of moving it into a c++ type, where you presumably consume it (send query) and throw it away.
alternately, and possibly better, can you just make a c++ string with the correct query text and use it? I don't think their printf wrapper is doing anything too extra special, and its kinda making a mess for you.
Last edited on Oct 8, 2019 at 7:01pm
Oct 8, 2019 at 8:34pm
> std::string str = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%d')", n);
memory leak
Topic archived. No new replies allowed.