Thread overview
Access violation with SDL_RenderText
Oct 27, 2006
mike
Oct 27, 2006
Johan Granberg
Oct 28, 2006
clayasaurus
Oct 28, 2006
mike
Oct 29, 2006
Bradley Smith
Oct 29, 2006
mike
October 27, 2006
Hi!

I'm doing some GUI stuff with SDL and I got those constantly changing values that I need to draw on the screen. The idea (if you don't know SDL) is that you create a new surface (a bitmap) every time the value changes, draw it to the screen and then delete the bitmap after drawing.

In pseudo code:

' surface = RenderText(value); // <- This function returns a pointer to a new surface (a struct)
' DrawSurface(surface);
' UpdateScreen();
' FreeSurface(surface);

Now that works so far. The problem is that my program crashes after some time - about two minutes when I'm constantly moving the mouse, forcing the GUI to redraw (access violation in the RenderText() line). Memory usage goes up a little, about 4k every 10-15 seconds, which makes me a bit suspicious, since I'm not newing anything at all, besides the surface I get returned from RenderText() which I delete anyway, using the FreeSurface() function.

So my question: Has anybody of you had this problem? Or any ideas? Could that be a GC issue? Maybe the GC wants to free something that doesn't exist anymore? I have no idea what's going wrong, so if someone could give me a hint I'd be very glad.

-Mike

-- 
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/
October 27, 2006
mike wrote:

> Hi!
> 
> I'm doing some GUI stuff with SDL and I got those constantly changing values that I need to draw on the screen. The idea (if you don't know SDL) is that you create a new surface (a bitmap) every time the value changes, draw it to the screen and then delete the bitmap after drawing.
> 
> In pseudo code:
> 
> ' surface = RenderText(value); // <- This function returns a pointer to a
> new surface (a struct)
> ' DrawSurface(surface);
> ' UpdateScreen();
> ' FreeSurface(surface);
> 
> Now that works so far. The problem is that my program crashes after some time - about two minutes when I'm constantly moving the mouse, forcing the GUI to redraw (access violation in the RenderText() line). Memory usage goes up a little, about 4k every 10-15 seconds, which makes me a bit suspicious, since I'm not newing anything at all, besides the surface I get returned from RenderText() which I delete anyway, using the FreeSurface() function.
> 
> So my question: Has anybody of you had this problem? Or any ideas? Could that be a GC issue? Maybe the GC wants to free something that doesn't exist anymore? I have no idea what's going wrong, so if someone could give me a hint I'd be very glad.
> 
> -Mike
> 

I don't know what is wrong but i had a similar problem myself also using SDL. I think it can bee related to string handling but is not sure, try calling gcfullcolect every frame and see if it helps, I got my memory leaks down to a tickle that way.
October 28, 2006
Johan Granberg wrote:
> mike wrote:
> 
>> Hi!
>>
>> I'm doing some GUI stuff with SDL and I got those constantly changing
>> values that I need to draw on the screen. The idea (if you don't know SDL)
>> is that you create a new surface (a bitmap) every time the value changes,
>> draw it to the screen and then delete the bitmap after drawing.
>>
>> In pseudo code:
>>
>> ' surface = RenderText(value); // <- This function returns a pointer to a
>> new surface (a struct)
>> ' DrawSurface(surface);
>> ' UpdateScreen();
>> ' FreeSurface(surface);
>>
>> Now that works so far. The problem is that my program crashes after some
>> time - about two minutes when I'm constantly moving the mouse, forcing the
>> GUI to redraw (access violation in the RenderText() line). Memory usage
>> goes up a little, about 4k every 10-15 seconds, which makes me a bit
>> suspicious, since I'm not newing anything at all, besides the surface I
>> get returned from RenderText() which I delete anyway, using the
>> FreeSurface() function.
>>
>> So my question: Has anybody of you had this problem? Or any ideas? Could
>> that be a GC issue? Maybe the GC wants to free something that doesn't
>> exist anymore? I have no idea what's going wrong, so if someone could give
>> me a hint I'd be very glad.
>>
>> -Mike
>>
> 
> I don't know what is wrong but i had a similar problem myself also using
> SDL. I think it can bee related to string handling but is not sure, try
> calling gcfullcolect every frame and see if it helps, I got my memory leaks
> down to a tickle that way.

If you pass d char[] into SDL's char* functions, like...

RenderText(char* text);

char[] w;
RenderText(w);

It might work sometimes but it is prone to crashing. Always use the std.toStringz() to turn D strings into C strings in this case.

I do not know if this is a problem though, just a guess. SDL has been stable otherwise.




October 28, 2006
Am 28.10.2006, 03:02 Uhr, schrieb clayasaurus <clayasaurus@gmail.com>:

>
> If you pass d char[] into SDL's char* functions, like...
>
> RenderText(char* text);
>
> char[] w;
> RenderText(w);
>
> It might work sometimes but it is prone to crashing. Always use the std.toStringz() to turn D strings into C strings in this case.
>
> I do not know if this is a problem though, just a guess. SDL has been stable otherwise.

I'm doing that already, and - oddly enough - this seems to be the problem.

' SDL_RenderText("text");

works.

' SDL_RenderText(toStringz("text"));

crashes after about two minutes, when I'm rendering text every frame. Also without toStringz I have no increase in memory usage, while with toStringz I have. Anyway, I'll post a solution once I find it.

-Mike


-- 
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/
October 29, 2006

mike wrote:

> 
> I'm doing that already, and - oddly enough - this seems to be the problem.
> 
> ' SDL_RenderText("text");
> 
> works.
> 
> ' SDL_RenderText(toStringz("text"));
> 
> crashes after about two minutes, when I'm rendering text every frame. Also without toStringz I have no increase in memory usage, while with toStringz I have. Anyway, I'll post a solution once I find it.

Perhaps you should buffer the text passed to SDL? Something like the following:

// Do this once in a constructor or globally
char* renderedTextBuffer = new char[1024];

// Do this to render text
if (value.length > renderedTextBuffer.length) {
  renderedTextBuffer = new char[value.length];
}
renderedTextBuffer[0 .. value.length] = value;
renderedTextBuffer[value.length] = 0;
RenderText(renderedText);

This is effectively what toStringz() does, but it won't allocate memory with every render.

  Bradley
October 29, 2006
Thanks! I'll give it a try. And if it doesn't work I'll try passing the (zero-terminated) char* pointer I get from my data source through to SDL, without buffering the results in an array like I do currently. That might be an even better way to do it anyway.

While debugging I somehow find it stranger and stranger -- in addition to crashing with toStringz it crashes when using my own function that fetches the values (get it, store it in an array, return it to render func), and crashes almost predictably in about half the time when fetching data AND using toStringz (after memory usage goes up half a meg). No crash when using a string constant. Could that be a multi-threading issue? I'm rendering the GUI in its own thread, so probably the GC collects stuff in the main thread that is currently in use in the render thread?

-Mike

> Perhaps you should buffer the text passed to SDL? Something like the following:
>
> // Do this once in a constructor or globally
> char* renderedTextBuffer = new char[1024];
>
> // Do this to render text
> if (value.length > renderedTextBuffer.length) {
>    renderedTextBuffer = new char[value.length];
> }
> renderedTextBuffer[0 .. value.length] = value;
> renderedTextBuffer[value.length] = 0;
> RenderText(renderedText);
>
> This is effectively what toStringz() does, but it won't allocate memory with every render.
>
>    Bradley



-- 
Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/