AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Is this a StrCat bug? (solved) (https://forums.alliedmods.net/showthread.php?t=132611)

step 07-16-2010 19:59

Is this a StrCat bug? (solved)
 
Hi, need a little help to understand a problem I'm having with this code:

PHP Code:

public Action:Command_Test(clientargs)
{
    
decl String:name[128];
    
decl String:temp[768];
    
    
name "initialized";
    
StrCat(tempsizeof(temp), name);
    
    
ChangeString(tempsizeof(temp));
    
PrintToConsole(client"%s"temp);
    
    return 
Plugin_Handled;
}

ChangeString(String:buffer[], maxlength)
{
    
decl String:str[32];
    
decl String:temp[128];
    
    if (
strlen(str) == 0)
    {
        
GetGameFolderName(strsizeof(str));
    }
    
    
BuildPath(Path_SMtempsizeof(temp), "logs\\%s.txt"str);
    
    
strcopy(buffermaxlengthstr);


The first response to the command will be:
Quote:

left4dead2
But the second one will be:
Quote:

left<04>
Why does this happen?


Another funny thing is that if I add
PHP Code:

decl String:whatever[32]; 

before the 'str' declaration, it will work properly.

Thanks

p3tsin 07-16-2010 20:20

Re: Is this a StrCat bug?
 
I would only expect that to produce garbage data. Why are you concatenating uninitialized strings in the first place, anyway? What are you trying to do?

step 07-16-2010 20:31

Re: Is this a StrCat bug?
 
Quote:

Originally Posted by p3tsin (Post 1241895)
I would only expect that to produce garbage data. Why are you concatenating uninitialized strings in the first place, anyway? What are you trying to do?

The only one that wasn't initialized was name, but even if it is, this will happen.
The actual code is bigger, but this replicates the problem. I don't want to repeat some of the instructions in ChangeString() if they are already found.

Seta00 07-16-2010 20:57

Re: Is this a StrCat bug?
 
In first place, what are you trying to do?

p3tsin 07-16-2010 21:11

Re: Is this a StrCat bug?
 
Quote:

Originally Posted by step (Post 1241902)
The only one that wasn't initialized was name, but even if it is, this will happen.

Dude, none of them were initialized. Let me break this down for you:

PHP Code:

public Action:Command_Test(clientargs)
{
    
decl String:name[128];    //declare variable name, contents: garbage
    
decl String:temp[768];    //declare variable temp, contents: garbage
    
    
name "initialized";        //assign a value to name
    
StrCat(tempsizeof(temp), name);    //concatenate name to temp; temp's contents are now something like this: nvgj9782hoinitialized

    
ChangeString(tempsizeof(temp));    //pass the mess to the other function, which overwrites the previous contents
    //after the function call temp may now contain the gamedir, or it may contain just more garbage
    
PrintToConsole(client"%s"temp);
    
    return 
Plugin_Handled;
}

ChangeString(String:buffer[], maxlength)
{
    
decl String:str[32];        //declare variable str, contents: garbage
    
decl String:temp[128];    //declare variable temp, contents: garbage
    
    
if (strlen(str) == 0)        //is str empty? (random result depends on the garbage content)
    
{
        
GetGameFolderName(strsizeof(str));
    }
    
    
BuildPath(Path_SMtempsizeof(temp), "logs\\%s.txt"str);    //build path with a potentially random string as the filename
    
    
strcopy(buffermaxlengthstr);    //copy the potentially random string to buffer


Can you please just explain what you're trying to achieve here, because that code isn't making much sense.

step 07-16-2010 21:51

Re: Is this a StrCat bug?
 
I just didn't want to initialize 'str', so I could know if the function ChangeString was being run by the first time.
Thanks for the help. I thought using 'decl' instead of 'new' was the best way, since strings are arrays. StrCat was the first function that didn't like it that way.

Anyway, it's fixed now. The real function is:

PHP Code:

CreateFilePath(String:buffer[], maxlength)
{
    
decl String:game[32] = "";
    
decl String:version[32] = "";
    
decl String:date[32];
    
decl String:temp[128];
    new 
ranbefore;
    
    if (
ranbefore == 0)
    {
        
// game name
        
GetGameFolderName(gamesizeof(game));
        
        
// game version
        
new Handle:file OpenFile("steam.inf""r");
        
ReadFileLine(filetempsizeof(temp));
        
CloseHandle(file);
        
TrimString(temp);
        new 
int;
        
int FindCharInString(temp'='false);
        
StrCat(versionsizeof(version), temp[int]);
        
ReplaceString(versionsizeof(version), "=""v");
        
ReplaceString(versionsizeof(version), ".""");
        
        
ranbefore 1;
    }
    
    
// date & time
    
FormatTime(datesizeof(date), NULL_STRING);
    
ReplaceString(datesizeof(date), "/""_");
    
ReplaceString(datesizeof(date), " - ""_");
    
ReplaceString(datesizeof(date), ":""_");
    
ReplaceString(datesizeof(date), " ""_");
    
    
// path
    
BuildPath(Path_SMtempsizeof(temp), "logs\\%s_%s_%s.txt"gameversiondate);
    
    
// return
    
strcopy(buffermaxlengthtemp);



Greyscale 07-16-2010 21:52

Re: Is this a StrCat bug?
 
Change your 'decl' to 'new' in your real source and see if that fixes it.

decl is allocating memory without clearing the contents of it. So random crap could be left in that memory, or it could be untouched memory (empty)

new allocates the memory and then empties its contents. 'decl' is just a more "lean" version of 'new' because it doesn't do any work clearing out the contents.

Moral of the story, only use 'decl' if you are going to copy your own known values to it.

EDIT:

You beat me.
But I see you have decl String:game[32] = "";
That is equivalent to using 'new'

step 07-16-2010 22:16

Re: Is this a StrCat bug?
 
Quote:

Originally Posted by Greyscale (Post 1241949)
You beat me.
But I see you have decl String:game[32] = "";
That is equivalent to using 'new'

You're right. And ranbefore won't work either since it's being set to 0 in every run. Any suggestions?

Greyscale 07-16-2010 22:24

Re: Is this a StrCat bug?
 
Use static instead of new.

If you declare a variable in a local function with the 'static' initializer then the value will be remembered. The only change you need to make is changing new to static.

Monkeys 07-16-2010 22:27

Re: Is this a StrCat bug?
 
Quote:

Originally Posted by Greyscale (Post 1241949)
But I see you have decl String:game[32] = "";
That is equivalent to using 'new'

Not that it matters in any way, but that's not entirely true ;p

decl String:game[32] = ""; sets game[0] to '\0' and the other chars remain garbage (although they'll never get read)
and new String:game[32]; sets everything to '\0'

EDIT: I'm saying this because you're better off using decl String:string[value] = ""; rather than new when value is rather high.


All times are GMT -4. The time now is 21:50.

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