Stephan Beal wrote:
> On Tue, Nov 1, 2011 at 11:25 PM, Tal Tabakman <tal.tabak...@gmail.com>wrote:
> 
>> second,needless to say that I want to avoid this since it causes mem
>> leaks.)
>>
> 
> Why would it leak? Are you intentionally NOT calling finalize()?
> 
> 
>>    sqlite3_prepare_v2(handle, query.str().c_str(),
>> query.str().length()+1, &m_entrySelectSnumStmt, 0);
>>
> 
> Technically speaking, the length you are passing there is not correct. The
> +1 accounts for the NUL byte at the end of the string, which prepare() does
> not need to see (that said, it seems harmless enough).

No. Take look at prepare_v2 documentation:

** ^If the nByte argument is less than zero, then zSql is read up to the
** first zero terminator. ^If nByte is non-negative, then it is the maximum
** number of  bytes read from zSql.  ^When nByte is non-negative, the
** zSql string ends at either the first '\000' or '\u0000' character or
** the nByte-th byte, whichever comes first. If the caller knows
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
** that the supplied string is nul-terminated, then there is a small
** performance advantage to be gained by passing an nByte parameter that
** is equal to the number of bytes in the input string <i>including</i>
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
** the nul-terminator bytes.
   ^^^^^^^^^^^^^^^^^^^^^^^^

FWIW, it seems, *only* case when it make sense to bother with nByte argument -
when string is *not* nul-terminated; otherwise, it is more efficient to just
pass -1, no matter if length is known or not.

And std::string::c_str() always nul-terminate string.

> Also, because 'query' is-a ostringstream, you are possibly creating 2 unneeded
> std::string copies here and you are definitely invoking undefined behaviour
> with this part:
> 
>    sqlite3_prepare_v2(handle, query.str().c_str(),
> 
> The problem is that query.str() returns a COPY of the string, which you
> call c_str() on to get its bytes, and then the copy is destroyed. It is
> "likely to work" on many platforms but it is technically undefined. To fix
> that:
> 
> std::string const & s( query.str() );
> 
> (note that a (const &) created this way is guaranteed to stay alive until
> the end of the scope)

Just get rid of str().length() and don't bother with this :-)

> Then use s.c_str() and s.size() instead of query.str().xxx().

_______________________________________________
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to