HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Memory Leaks with a lot of String variables?

12-25-2004, 11:46 PM#1
Dalten
My latest project uses a dialog system that works like this:

1 string, contains the lines for what a unit is going to say.

The String is defined when the game starts in an array, where all my dialogs are stored as well. One NPC might have 5 or 6 strings that belong to him.

When you speak to the proper NPC, it parses the one string and splits it up into another array, one variable for each LINE. It knows when to find another line because I have the end of the would-be line marked with a |.

Then, once all that is set up, It turns on a 0.03 second period event trigger that generates a 1 letter at a time effect. The text is displayed in a multiboard that shrinks and grows depending on how large the data is. This works beautifully, but it leaks a LOT of memory. First off, since i'm a novice in memory leak detection, can anyone point out some obvious leaks or perhaps show me a way to do this without it leaking like an SOB? I DONT use local variables, but perhaps I should start, because I really want to use this system but not if it's going ot leak memory the way it is. I don't really know how, as up until now I haven't had much of a use for JASS since GUI was functional enough.

Anyway, here i've posted the two triggers, they're kinda long.




Quote:
Interact with a Villager
Events
Unit - A unit Begins casting an ability
Conditions
(Ability being cast) Equal to (==) Interact (Thief)
(Level of (Target unit of ability being cast)) Greater than (>) 1
((Target unit of ability being cast) is owned by Player 12 (Brown)) Equal to (==) False
Actions
Set INT_LineCounter = 1
Set INT_TextScroll = 1
Set INT_CV = (Custom value of (Target unit of ability being cast))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Or - Any (Conditions) are true
Conditions
INT_ClassID[INT_CV] Equal to (==) 0
DIAL_VSetup[INT_ClassID[INT_CV]] Equal to (==) <Empty String>
Then - Actions
Game - Display to (All players) the text: |cffffcc00That targ...
Skip remaining actions
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Remaining time for TIM_SpeechReset[INT_ClassID[INT_CV]]) Less than or equal to (<=) 0.00
Then - Actions
Set INT_ChatCounter[INT_ClassID[INT_CV]] = 0
Else - Actions
Set MULTI_Dialog = No multiboard
Multiboard - Destroy MULTI_Dialog
Set INT_DialogLength = 0
For each (Integer A) from 1 to 25, do (Actions)
Loop - Actions
Set STR_DStrings[(Integer A)] = <Empty String>
Set INT_LStart[(Integer A)] = 1
Set INT_Letter[(Integer A)] = 0
Set INT_CLetter = 0
Set STR_FinalStrings[(Integer A)] = <Empty String>
-------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= --------
Multiboard - Change the display style of MULTI_Stats to Hide
Multiboard - Create a multiboard with 1 columns and 21 rows, titled Shouldn't See This
Set MULTI_Dialog = (Last created multiboard)
Multiboard - Set the width for MULTI_Dialog item in column 1, row 0 to 22.00% of the total screen width
Multiboard - Set the display style for MULTI_Dialog item in column 1, row 0 to Show text and Hide icons
Multiboard - Change the display style of MULTI_Dialog to Show
-------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= --------
Set INT_DialogMax = (Integer((Substring(DIAL_VSetup[INT_ClassID[INT_CV]], 5, 6))))
Set INT_ChatCounter[INT_ClassID[INT_CV]] = (INT_ChatCounter[INT_ClassID[INT_CV]] + 1)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
INT_ChatCounter[INT_ClassID[INT_CV]] Greater than (>) INT_DialogMax
Then - Actions
Set INT_ChatCounter[INT_ClassID[INT_CV]] = INT_DialogMax
Else - Actions
Set INT_DialogSTRNumber = ((Integer((Substring(DIAL_VSetup[INT_ClassID[INT_CV]], 1, 4)))) + (INT_ChatCounter[INT_ClassID[INT_CV]] - 1))
Set STR_UnitName = (Substring(DIAL_VSetup[INT_ClassID[INT_CV]], 7, (Length of DIAL_VSetup[INT_ClassID[INT_CV]])))
Set INT_TextScroll = 6
Set INT_DialogLength = (Length of DIAL_Villager[INT_DialogSTRNumber])
Set STR_DialogText = (Substring(DIAL_Villager[INT_DialogSTRNumber], 1, INT_DialogLength))
-------- =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= --------
For each (Integer A) from 1 to INT_DialogLength, do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Substring(STR_DialogText, (Integer A), (Integer A))) Equal to (==) |
Then - Actions
Set STR_DStrings[INT_LineCounter] = (Substring(STR_DialogText, INT_LStart[INT_LineCounter], ((Integer A) - 1)))
Set INT_DLength[INT_LineCounter] = (Length of STR_DStrings[INT_LineCounter])
Set INT_LineCounter = (INT_LineCounter + 1)
Set INT_LStart[INT_LineCounter] = ((Integer A) + 1)
Else - Actions
Set INT_DialogLength = 0
Set INT_LineCounter = (INT_LineCounter - 1)
For each (Integer A) from 1 to INT_LineCounter, do (Actions)
Loop - Actions
Set INT_DialogLength = (INT_DialogLength + INT_DLength[(Integer A)])
Unit - Order (Target unit of ability being cast) to Stop
Unit - Make (Target unit of ability being cast) face (Triggering unit) over 0.00 seconds
Multiboard - Change the title of MULTI_Dialog to STR_UnitName
Multiboard - Change the number of rows for MULTI_Dialog to INT_LineCounter
Countdown Timer - Start T_BoardDisplay as a One-shot timer that will expire in ((Real(INT_LineCounter)) x 4.00) seconds
Countdown Timer - Start TIM_SpeechReset[INT_ClassID[INT_CV]] as a One-shot timer that will expire in 25.00 seconds
Set INT_Letter[1] = 5
Trigger - Turn on Letter Server <gen>


Here is the Letter Server trigger:

Quote:
Letter Server
Events
Time - Every 0.02 seconds of game time
Conditions
Actions
Set INT_CLetter = (INT_CLetter + 1)
Set INT_LLength = 0
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
INT_CLetter Greater than or equal to (>=) (INT_DialogLength + 6)
Then - Actions
Trigger - Turn off (This trigger)
Else - Actions
For each (Integer Integer_A) from 1 to INT_LineCounter, do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
INT_CLetter Greater than or equal to (>=) INT_LLength
INT_Letter[Integer_A] Greater than or equal to (>=) 1
Then - Actions
Set INT_Letter[Integer_A] = (INT_Letter[Integer_A] + 1)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
INT_Letter[Integer_A] Equal to (==) (Length of STR_DStrings[Integer_A])
Then - Actions
Set INT_Letter[(Integer_A + 1)] = 5
Else - Actions
For each (Integer Integer_B) from 1 to 5, do (Actions)
Loop - Actions
Set CText[Integer_B] = (Substring(STR_DStrings[Integer_A], (INT_Letter[Integer_A] - (5 - Integer_B)), (INT_Letter[Integer_A] - (5 - Integer_B))))
Set STR_FinalStrings[Integer_A] = (CC[1] + ((Substring(STR_DStrings[Integer_A], 1, (INT_Letter[Integer_A] - 5))) + (E + (CC[2] + (CText[1] + (E + (CC[3] + (CText[2] + (E + (CC[4] + (CText[3] + (E + (CC[5] + (CText[4] + (E + (CC[6] + (CText[5] + E)))))))))))))))))
Multiboard - Set the text for MULTI_Dialog item in column 1, row Integer_A to STR_FinalStrings[Integer_A]
Else - Actions
Set INT_LLength = (INT_LLength + (Length of STR_DStrings[Integer_A]))
12-28-2004, 03:42 PM#2
aaero
I'm pretty sure this doesn't leak. What led you to believe it leaked?

I think it's very possible it lags, but before dealing with that I'd like to find out why you thought it leaked in the first place.

This thread is where I first went to read about leaks, and Cubasis mentions a very key point: strings don't leak memory (and neither do integers).

So, does it leak, or just lag?
12-28-2004, 04:32 PM#3
Dalten
Quote:
Originally Posted by aaero
I'm pretty sure this doesn't leak. What led you to believe it leaked?

I think it's very possible it lags, but before dealing with that I'd like to find out why you thought it leaked in the first place.

This thread is where I first went to read about leaks, and Cubasis mentions a very key point: strings don't leak memory (and neither do integers).

So, does it leak, or just lag?

When I watch the mem usage of wc3.exe, it jumps up fast when i am talking to my NPC's. It goes up at a rate of about a meg a minute or so. It really don't lag at all, i'm just worried about it becoming unplayable after awhile.

Example: When my War3 just started up, it's mem usage is 149,556k. Now, i'll run through all my dialogs(note, all my NPC's are the in same place so it's not like it has to load other parts of the map into memory, etc).: New mem usage: 162, 428k. This is after running through all my dialogs. I thought maybe something else I was doing was causing it, but when I just let the game sit there it doesn't really leak any memory at all.

I have a gig of ram so this doesn't lag me at all, but i'm worried about other people lagging because if I put in all the dialogs I want, it would probably leak to upwards of 300,000k or more.

Thanks for looking at it for me.
12-28-2004, 05:26 PM#4
LegolasArcher
http://www.wc3campaigns.com/showthread.php?t=69170

That answers your question. The way WC3 handles string variables causes this issue, it seems.
12-28-2004, 06:50 PM#5
aaero
Wow, good find Legolas. That thread details your problem pretty well. I also didn't know that, so good info.
12-28-2004, 08:25 PM#6
Dalten
That really effing sucks if that's the case. Thanks for pointing that out. I guess I'll have to make my dialogs a lot simpler or begin to petition blizzard for a fix.