String::empty reference counting bug


#1

Hi,

The following code causes a wrong free() call:

  String crack(T("crack"));
  for (int i = 0; i < 0x40000000; ++i)
  {
    String s;
    s = crack;
  }

The problem is related to the reference counting of String::emptyString. Each time the “s = crack” code is executed, the number of references of String::emptyString is decremented until reaching 0, which causes the (statically allocated) empty string to be freed.

Here is a dirty hack in String::operator= (const String& other):

        if (text != &emptyString && atomicDecrementAndReturn (text->refCount) == 0)
            juce_free (text);

But I think that there is probably a better way to solve the problem.

Regards,

Francis.


#2

Hmm… nasty. Ok, I’d suggest a slightly different approach:

[code]String::~String() throw()
{
emptyString.refCount = safeEmptyStringRefCount;

if (atomicDecrementAndReturn (text->refCount) == 0)
    juce_free (text);

}
[/code]

Bit of a shame to have to call that in every destructor, but it should sort out the problem.


#3

Oh, that’s interesting. I was getting crashes in String, but had assumed something else was trashing the memory and this is where it manifested.

I’ll see if that helps me too.

Bruce