PDA

View Full Version : Puzzled about how QString allocates memory



feraudyh
28th December 2013, 18:58
Hello all,
I'm using some C functions that expect old fashionned ascii string paths, but I'm using Qt utilities to handle the paths.
Here is a sample static method I wrote:

char *PathUtil::toWinAscii(QString fullpath)
{
QByteArray ba = fullpath.toLocal8Bit();
char *s = ba.data();
#if WIN32
char *p = s;
while(*p){if(*p == '/')*p = '\\'; p++;}// convert Qt's separators to Windows compatible separators
#endif
return s;
}

Now if I do thousands of calls of this function (because I'm dealing with thousands of files), I expect to get a lot of memory eaten up.
Should I free the memory allocated by data() with free or delete []?
My guess is that I should get into the sources, but I still wonder whether this is discussed in the documentation.

UPDATE:
Sorry, but I am not sure if it really works at all. Is the value being returned treated as an "automatic variable", and disappear on return from the method?

ChrisW67
28th December 2013, 21:05
QByteArray::data() does not allocate new memory and make a copy, it merely provides a pointer the the QByteArray's internal buffer. This buffer will be valid as long as the QByteArray is in scope and not modified. If you want your own copy of this data then you need to make it yourself.

In your example the QByteArray goes out of scope at the end of the function. at this point the internal buffer of the byte array is deallocated and potential reused by other memory allocations. Using your returned pointer after this will eventually (if not immediately) crash your program.

feraudyh
29th December 2013, 20:50
Yes, I think you understood perfectly what I was assuming, which was wrong.
I rewrote the signature and implementation as



void PathUtil::toWinAscii(QString fullpath, char *destination)
{
QByteArray ba = fullpath.toLocal8Bit();
char *s = ba.data();
#if WIN32
char *p = destination;
while(*p){if(*p == '/')*p = '\\'; p++;}
#endif*
strcpy(destination, s);
}

and assuming that destination is allocated this works fine.
Thankyou

wysota
29th December 2013, 21:08
strcpy() is available on WIN32 as well, that's one thing. The other is that there is still no memory allocation here. If "destination" points to a buffer that is not big enough to hold the full path, you will end up with a buffer overflow.

The easiest way to safely have the path with native separators is to use QDir::toNativeSeparators().