14 Feb, 2014, Davenge wrote in the 1st comment:
Votes: 0
The code looks like a little like this:

void command( args )
{
char buf[MAX_BUFFER];

}


When I run the "command" twice, buf is holding it's contents from the previous run through. I was under the impression that any memory set up during the method in a standard declaration like this was cleared when the method was done running. It's acting like a static variable. I'm a little confused, but maybe I misunderstood it to start.

Obviously, I can just memset it at the start of the method but I didn't think I had to on a non-static.
14 Feb, 2014, quixadhal wrote in the 2nd comment:
Votes: 0
Another reason C (and C++) are horrible languages. :)

No, the specifications for C say that a buffer is not GUARENTEED to retain its contents after it falls out of scope, unless declared static.

What often happens is this. You declare some variable in a function. You are too lazy to initialize it, or mistakenly assume the compiler initializes it for you. You stick a value in it and exit the function. Now, the next time you run the function, if nothing else has allocated the memory that was just freed, odds are good you'll re-allocate the exact same piece of memory again. This is especially true of modern OS's with memory paging, since that page likely is still in memory and hasn't been freed or reused by anything else yet.

So, now, when you re-enter the function, it has the values it had before, because nothing cleared it. You didn't clear it on entry to the function. The compiler didn't clear it, because that's not required (and is sub-optimal if speed is important), and the OS didn't clear it because it was never really returned to the OS free pool.

When coding in C or C++, you should always initialize every variable to some known value, as it helps you track down errors later.

void command ( const char *args ) {
char buf[MAX_BUFFER] = "\0\0\0\0"; /* Use 4 bytes for 32-bit platforms, 8 bytes for 64-bit platforms */

}
14 Feb, 2014, Davenge wrote in the 3rd comment:
Votes: 0
Hmm, good to know. I just assumed that memory was cleared when the method stopped unless static. No biggy, will just memset from now on xD
14 Feb, 2014, quixadhal wrote in the 4th comment:
Votes: 0
Be aware that this also affects normal variables, not just pointers. C relies on you to initialize every variable to a sane state.
14 Feb, 2014, Rarva.Riendf wrote in the 5th comment:
Votes: 0
Better yet, initialize variable with known value that will either crash or raise a bug as soon as possible. It help detects problems when you think an algorythm is fine, but in truth some part of it are never ever used (and thus your value stay at 'will crash if used'.
i
15 Feb, 2014, Tyche wrote in the 6th comment:
Votes: 0
quixadhal said:
What often happens is this. You declare some variable in a function. You are too lazy to initialize it, or mistakenly assume the compiler initializes it for you. You stick a value in it and exit the function. Now, the next time you run the function, if nothing else has allocated the memory that was just freed, odds are good you'll re-allocate the exact same piece of memory again. This is especially true of modern OS's with memory paging, since that page likely is still in memory and hasn't been freed or reused by anything else yet.

While it's possible that a C/C++ implementation might exist that dynamically allocate and free memory upon function call and return, the above scenario which describes dynamic allocation is not very likely. Typically automatic variables are located on the stack along with return addresses and registers.
For example:
(gdb) list
1 void command( args )
2 {
3 char buf[140];
4 }

(gdb) disass command
Dump of assembler code for function command:
0x00000001004010d0 <+0>: push %rbp
0x00000001004010d1 <+1>: mov %rsp,%rbp
0x00000001004010d4 <+4>: sub $0x90,%rsp
0x00000001004010db <+11>: mov %ecx,0x10(%rbp)
0x00000001004010de <+14>: add $0x90,%rsp
0x00000001004010e5 <+21>: pop %rbp
0x00000001004010e6 <+22>: retq
End of assembler dump.
15 Feb, 2014, quixadhal wrote in the 7th comment:
Votes: 0
That sounds correct Tyche.

I'm going to go ahead and assume the compiler would reuse the same string buffer space, and thus end up pushing the same address it last popped more often than not. If that's true, my theory is still valid in general. The memory never gets cleared (unless YOU do it), and it gets recycled. That would make it far less likely that non-pointer variables would keep their same value (odds are, they'd get different random values).

Thanks for clarifying that. It's been a while since I played with assembly… nice to see again, actually. :)
16 Feb, 2014, Tyche wrote in the 8th comment:
Votes: 0
It's only going to contain the same data if the function is called at the same call level, and there are no intervening calls to other functions which contain local variables.

int main() {
command(args);
command(args); /* buf will contain whatever first call placed there */
some_func();
command(args); /* buf will contain whatever local variables were used in some_func() */
}

The stack pointer traditionally pointed to a fixed address, but newer operating systems now randomize the stack location for security reasons.
On Windows, I believe that started with 64-bit versions.
0.0/8