[Qt-interest] Segmentation fault while converting from QString to char*

Nikos Chantziaras realnc at arcor.de
Mon Apr 19 18:35:59 CEST 2010


strncpy() copies *at most* 'file_name_size' characters, not *exactly* 
'file_name_size' characters.  It's just a strcpy() with a safeguard to 
avoid writing past the end of the target (which causes a segfault). 
Which is what we want, since if there are more characters in 'ba' than 
what 'file_name' can hold, we get a segfault.

NULL-terminating the result in case 'file_name' is smaller than 'ba' is 
important if further use of 'file_name' expects it to be 
NULL-terminated.  In that case, one additional line makes the code 
rock-solid against segfaults for all intents and purposes in that 
particular section of the code:

   QByteArray ba = qt_file_name.toLatin1();
   strncpy(file_name, ba.constData(), file_name_size);
   file_name[file_name_size - 1] = '\0';

(That last line is for the case where 'file_name_size' is equal to 
ba.size().  strncpy() will not attempt to put a '\0' at the end if 
there's no space left for it.)

Of course, this only guards against this particular error.  A real 
application would need to provide a way to tell the caller that the 
result won't fit in 'file_name'.  With exception handling, something 
like this:

   QByteArray ba = qt_file_name.toLatin1();

   if (ba.size() >= file_name_size)
       // throw an exception here

   // If we get here, it's guaranteed to fit, including '\0'.
   strcpy(file_name, ba.constData());


If the logic of the surrounding application code would work in a way 
that this is not supposed to happen at all, then you can use a Q_ASSERT:

   // If this is triggered, the logic is wrong.
   Q_ASSERT(ba.size() < file_name_size);

   QByteArray ba = qt_file_name.toLatin1();
   strcpy(file_name, ba.constData());

But since we don't know the details here we can come up with better 
mouse traps all day long :)


On 04/19/2010 07:14 PM, Alexandre Beraud wrote:
> You have to copy the exact number of bytes pointed to by constData(),
> not the arbitrary size of the future container. Depending on the
> encoding, the size might not be the number of characters in the QString.
> Try ba.size()+1, since the byte at position size() is '\0' and you will
> need it to mark the end of your array of characters.
>
> Regards,
>
> Alex
>
>
> Nikos Chantziaras a écrit :
>> Try:
>>
>> QByteArray ba = qt_file_name.toLatin1();
>> strncpy(file_name, ba.constData(), file_name_size);
>>
>> 'file_name_size' is the size of the 'file_name' target buffer (for
>> example "100" if you allocated file_name with "file_name = new
>> char[100]".)
>> _______________________________________________
>> Qt-interest mailing list
>> Qt-interest at trolltech.com
>> http://lists.trolltech.com/mailman/listinfo/qt-interest
>>
>
>




More information about the Qt-interest-old mailing list