0

I am writing a chess engine and to get pseudo-random moves, I pass a move generation function an array to fill. Here is some code:

...

else if(pstrcmp(input, (char*)"check", 5)){
            int checkIndex = getIndex(input[6], input[7] - 49);
            printf("checkindex %i\n", checkIndex);
            if(!(checkIndex < 0 || checkIndex > 127)){
                //we've received a valid check
                struct m mUn[MOVE_BUFF];
                gen_psm(checkIndex, mUn);
                int i = 0;
                while(mUn[i].start != mUn[i].end && i < MOVE_BUFF){
                    printf("%s\n", GSQ(mUn[i].end));
                    i++;
                }
            }
        }

...

The first line is just some input checking. The meat of the code is between struct m mUn[MOVE_BUFF] and the while loop. So I create a struct m array, which I created and it holds a few ints that specifies a specific move, and then I pass it to gen_psm which takes an index of the square to check and an array to fill. It fills the array with valid moves for the piece located at the index. Fine and dandy for the first move. Then I try the second move, and I find that the array still has the data in it from the first move, even though I have long exited the scope of the mUn where I declared it. Is it some nature of structs that it retains its data? Do I need to 0 fill the whole thing (it seemed to be full of 0's when I tried it). If I need to 0 fill it, is there a faster way (if I have to 0 fill it several 100 million times, that's a problem)?

Eric Thoma
  • 5,905
  • 6
  • 30
  • 40
  • 1
    Please specify either `C` or `C++`. I am going to assume `C` based on function calls, and the fact that you are casting a string literal as a `char*`. – Joe Mar 14 '12 at 20:24
  • possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – fredoverflow Mar 14 '12 at 20:30
  • The best is possibly to use a global/static array with moves, and use it as a stack. Fixed size (about 60 * 2 * 30), and put in a couple of asserts to check for out-of-bound. – wildplasser Mar 14 '12 at 20:41

5 Answers5

7

There is nothing in the standard that guarantees that the memory of a local variable which has left scope will be changed, it is simply undefined behavior to read it. The compiler may zero it, it may not, it may insert a smiley into the beginning of it. It is unspecified as to what will happen to that memory location after the variable is out of scope.

Simply declaring an array ensures that space will be reserved for it, but it does not initialize each member. You can memset it or just initialize each one in a loop.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
  • Yes. Or to explain the behaviour of this program: creating new local variables does not clear them. They just have whatever value happens to be in that mamory location/ And if you run the same routine twice, the local variables that get created the second time may just get the same memory address as the first time. – Mr Lister Mar 14 '12 at 20:27
2

Try

struct m mUn[MOVE_BUFF] = {0};

(You may want to pick a better name for your struct than simply 'm')

Happy Green Kid Naps
  • 1,611
  • 11
  • 18
1

There's no guarantee that the data will be cleared and for performance purposes it isn't cleared when scope is exited it is just undefined behavior to read or modify it.

Although in the case of debuggers it might fill the page with a POISON marker to check for out of bounds accesses such as valgrind's memcheck.

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
1

You have no guarantee what the compiler will do with memory your not using. Generally it just leaves it alone. If you want your memory initialized you must initialize it. Large sections of memory can be efficienly set to zero with memset(), but make sure you're not touching memory you don't own.

John Gordon
  • 2,576
  • 3
  • 24
  • 29
0

The real answer is "why would it reset itself?" If you haven't initialized the memory, it's by definition in an undefined state. (The fact that it may be hex zeros on the first run through is not something you can rely upon at all.)

You've definitely got to flush it.

As far as the quickest way to go about that, well...

memset would be my first try. If that was really just too slow I'd probably create a dummy structure of the same size, fill THAT with nulls and do a memcpy from it over the top of the local one. It's ugly, but I don't expect you'll get anything faster than that.

Michael Wilson
  • 442
  • 1
  • 4
  • 11