segmentation fault with string and char*

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!
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
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.



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?
Yeah, that too :)
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
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
> std::string str = sqlite3_mprintf("INSERT INTO table (number) VALUES ('%d')", n);
memory leak
Topic archived. No new replies allowed.