Raised This Month: $51 Target: $400
 12% 

Memory Leak?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
ThatKidWhoGames
Veteran Member
Join Date: Jun 2013
Location: IsValidClient()
Old 03-07-2018 , 08:56   Memory Leak?
Reply With Quote #1

Just want to make sure my code here won't cause any memory leaks:
PHP Code:
#pragma semicolon 1
#define PLUGIN_VERSION "1.0"

#include <shop>
#include <sourcemod>
#include <morecolors>

Handle hAnswerTimer;
int iAnsweriPoints;
bool bActive;

public 
Plugin myinfo = {
    
name         "[TF2] Shop! - Math Module",
    
author         "Sgt. Gremulock",
    
description "Shop/store math module.",
    
version     PLUGIN_VERSION,
    
url         "sourcemod.net"
};

public 
void OnPluginStart()
{
    
CreateTimer(90.0Timer_Problem_TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);

    
AddCommandListener(Command_Say"say");
    
AddCommandListener(Command_Say"say_team");
}

public 
Action Command_Say(int client, const char[] commandint argc)
{
    if (
bActive && argc == 1)
    {
        
char arg1[32];
        
GetCmdArg(1arg1sizeof(arg1));

        if (
StringToInt(arg1) == iAnswer)
        {
            
CPrintToChatAll("%s {lightgreen}%N{default} answered the question correctly. The answer was {lightgreen}%i{default}."CTAGclientiAnswer);
            
Shop_AddPoints(clientiPoints);

            if (
hAnswerTimer != null)
            {
                
KillTimer(hAnswerTimer);
                
hAnswerTimer null;
            }

            
ResetValues();
        }
    }
}

public 
Action Timer_Problem(Handle timerany data)
{
    
bActive true;
    
iPoints GetRandomInt(110);
    
int one GetRandomInt(1100), two GetRandomInt(1100), operation GetRandomInt(12);

    
char buffer[256];

    switch (
operation)
    {
        case 
1:
        {
            
buffer     "+";
            
iAnswer one two;
        }

        case 
2:
        {
            
buffer     "-";
            
iAnswer one two;
        }
    }

    
Format(buffersizeof(buffer), "%s Math problem for {lightgreen}%i {default}point(s): What is {lightgreen}%i {red}%s {lightgreen}%i{default}?"CTAGiPointsonebuffertwo);
    
CPrintToChatAll(buffer);

    
hAnswerTimer CreateTimer(15.0Timer_AnswerTimer_TIMER_FLAG_NO_MAPCHANGE);
}

public 
Action Timer_AnswerTimer(Handle timerany data)
{
    
CPrintToChatAll("%s Time is up! The correct answer was {lightgreen}%i{default}."CTAGiAnswer);
    
ResetValues();
    
hAnswerTimer null;
}

void ResetValues()
{
    
bActive         false;
    
iAnswer         0;
    
iPoints         0;

Thanks,
Grant

EDIT: Out of curiosity, is setting an array = null the same as closing its handle or deleting it?

Last edited by ThatKidWhoGames; 03-07-2018 at 08:59.
ThatKidWhoGames is offline
Fyren
FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren FyrenFyrenFyrenFyrenFyren
Join Date: Feb 2106
Old 03-07-2018 , 09:21   Re: Memory Leak?
Reply With Quote #2

Quote:
Originally Posted by ThatKidWhoGames View Post
Just want to make sure my code here won't cause any memory leaks:
Make sure every time you create a handle, it will get closed. You have to consider every code path.

You can use sm_dump_handles as a rough way to check. Run your plugin for a long time, see if the number of handles is the expected value or if it's ballooning.

Quote:
Originally Posted by ThatKidWhoGames View Post
Out of curiosity, is setting an array = null the same as closing its handle or deleting it?
No.
Fyren is offline
ThatKidWhoGames
Veteran Member
Join Date: Jun 2013
Location: IsValidClient()
Old 03-07-2018 , 09:29   Re: Memory Leak?
Reply With Quote #3

Quote:
Originally Posted by Fyren View Post
Make sure every time you create a handle, it will get closed. You have to consider every code path.

You can use sm_dump_handles as a rough way to check. Run your plugin for a long time, see if the number of handles is the expected value or if it's ballooning.



No.
Thank you very much,
Grant
ThatKidWhoGames is offline
cravenge
Veteran Member
Join Date: Nov 2015
Location: Chocolate Factory
Old 03-07-2018 , 09:31   Re: Memory Leak?
Reply With Quote #4

Quote:
Originally Posted by ThatKidWhoGames View Post
EDIT: Out of curiosity, is setting an array = null the same as closing its handle or deleting it?
Clearing arrays is much better.
cravenge is offline
pride95
Senior Member
Join Date: Aug 2015
Old 03-07-2018 , 10:07   Re: Memory Leak?
Reply With Quote #5

why are you setting TIMER_FLAG_NO_MAPCHANGE on a timer in OnPluginStart?
use delete hAnswerTimer; instead of killtimer and hAnswerTimer = null;
also check in OnMapEnd if hAnswerTimer != null;
pride95 is offline
Visual77
Veteran Member
Join Date: Jan 2009
Old 03-07-2018 , 10:10   Re: Memory Leak?
Reply With Quote #6

I'd reset hAnswerTimer to null on public void OnMapStart()

Because TIMER_FLAG_NO_MAPCHANGE will kill the timer, but it will not reset the timer handle back to null.

edit: pride95 beat me to it.

Last edited by Visual77; 03-07-2018 at 10:21.
Visual77 is offline
pride95
Senior Member
Join Date: Aug 2015
Old 03-07-2018 , 12:59   Re: Memory Leak?
Reply With Quote #7

Quote:
Originally Posted by Visual77 View Post
I'd reset hAnswerTimer to null on public void OnMapStart()

Because TIMER_FLAG_NO_MAPCHANGE will kill the timer, but it will not reset the timer handle back to null.

edit: pride95 beat me to it.
TIMER_FLAG_NO_MAPCHANGE its useless in OnPluginStart();
if the plugin is unloaded, the timer is cleared automatically. so you dont need this flag.
OnPluginStart is called once, not like OnMapStart() which is called on every map.

delete the timer OnMapEnd, don't send more memory when the map is changed.

Last edited by pride95; 03-07-2018 at 13:00.
pride95 is offline
Visual77
Veteran Member
Join Date: Jan 2009
Old 03-07-2018 , 13:10   Re: Memory Leak?
Reply With Quote #8

Quote:
Originally Posted by pride95 View Post
TIMER_FLAG_NO_MAPCHANGE its useless in OnPluginStart();
if the plugin is unloaded, the timer is cleared automatically. so you dont need this flag.
OnPluginStart is called once, not like OnMapStart() which is called on every map.

delete the timer OnMapEnd, don't send more memory when the map is changed.
We are talking about different timers. Yes, there's clearly a mistake in OnPluginStart() too. (TIMER_FLAG_NOMAPCHANGE is not suitable there), however on the other timer, it is but he will
then have to set both the timer handle to null and call ResetValues() in OnMapStart() for those rare cases where the timer is destroyed automaticly when the map changes.

Last edited by Visual77; 03-07-2018 at 13:32.
Visual77 is offline
ThatKidWhoGames
Veteran Member
Join Date: Jun 2013
Location: IsValidClient()
Old 03-09-2018 , 09:42   Re: Memory Leak?
Reply With Quote #9

Thanks for the help. So by my understanding, this should fix all the stuff you guys talked about?
PHP Code:
#pragma semicolon 1
#define PLUGIN_VERSION "1.0"

#include <shop>
#include <sourcemod>
#include <morecolors>

Handle hAnswerTimer;
int iAnsweriPoints;
bool bActive;

public 
Plugin myinfo = {
    
name         "[TF2] Shop! - Math Module",
    
author         "Sgt. Gremulock",
    
description "Shop/store math module.",
    
version     PLUGIN_VERSION,
    
url         "grem-co.com"
};

public 
void OnPluginStart()
{
    
CreateTimer(90.0Timer_Problem_TIMER_REPEAT);

    
AddCommandListener(Command_Say"say");
    
AddCommandListener(Command_Say"say_team");
}

public 
void OnMapStart()
{
    
ResetValues();
    
hAnswerTimer null;
}

public 
Action Command_Say(int client, const char[] commandint argc)
{
    if (
bActive && argc == 1)
    {
        
char arg1[32];
        
GetCmdArg(1arg1sizeof(arg1));

        if (
StringToInt(arg1) == iAnswer)
        {
            
CPrintToChatAll("%s {lightgreen}%N{default} answered the question correctly. The answer was {lightgreen}%i{default}."CTAGclientiAnswer);
            
Shop_AddPoints(clientiPoints);

            if (
hAnswerTimer != null)
                        {
                               
KillTimer(hAnswerTimer);
                               
hAnswerTimer null;
                        }

            
ResetValues();
        }
    }
}

public 
Action Timer_Problem(Handle timerany data)
{
    
bActive true;
    
iPoints GetRandomInt(110);
    
int one GetRandomInt(1100), two GetRandomInt(1100), operation GetRandomInt(12);

    
char buffer[256];

    switch (
operation)
    {
        case 
1:
        {
            
buffer     "+";
            
iAnswer one two;
        }

        case 
2:
        {
            
buffer     "-";
            
iAnswer one two;
        }
    }

    
Format(buffersizeof(buffer), "%s Math problem for {lightgreen}%i {default}point(s): What is {lightgreen}%i {red}%s {lightgreen}%i{default}?"CTAGiPointsonebuffertwo);
    
CPrintToChatAll(buffer);

    
hAnswerTimer CreateTimer(15.0Timer_AnswerTimer_TIMER_FLAG_NO_MAPCHANGE);
}

public 
Action Timer_AnswerTimer(Handle timerany data)
{
    
CPrintToChatAll("%s Time is up! The correct answer was {lightgreen}%i{default}."CTAGiAnswer);
    
ResetValues();
    
hAnswerTimer null;
}

void ResetValues()
{
    
bActive         false;
    
iAnswer         0;
    
iPoints         0;

Thanks,
Grant

Last edited by ThatKidWhoGames; 03-09-2018 at 09:52.
ThatKidWhoGames is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:23.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode