为什么局部变量结构在离开其范围时不会重置?

时间:2012-03-14 20:21:10

标签: c struct chess

我正在编写一个国际象棋引擎并获得伪随机移动,我将一个移动生成函数传递给一个数组来填充。这是一些代码:

...

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++;
                }
            }
        }

...

第一行只是一些输入检查。代码的内容介于struct m mUn[MOVE_BUFF]和while循环之间。所以我创建了一个struct m数组,我创建了它,并且它包含一些指定特定移动的整数,然后我将它传递给gen_psm,它将要检查的方形索引和一个数组到填。它为数组填充了位于索引处的片段的有效移动。第一步,精致和花花公子。然后我尝试第二步,我发现数组从第一步开始仍然有数据,即使我已经退出了我声明它的mUn的范围。结构的某些性质是否会保留其数据?我是否需要填充整个事物(当我尝试它时似乎充满了0)。如果我需要0填充它,是否有更快的方法(如果我必须填写它1亿次,这是一个问题)?

5 个答案:

答案 0 :(得分:7)

标准中没有任何内容可以保证已经改变了已经保留范围的局部变量的内存,它只是未定义的行为来读取它。编译器可以将其归零,也可以不归零,它可以在其开头插入笑脸。没有具体说明变量超出范围后该内存位置会发生什么。

简单地声明一个数组可确保为其保留空间,但它不会初始化每个成员。您可以memset或者只是循环初始化每个。

答案 1 :(得分:2)

尝试

struct m mUn[MOVE_BUFF] = {0};

(您可能希望为结构选择一个更好的名称,而不仅仅是'm')

答案 2 :(得分:1)

无法保证数据将被清除,出于性能目的,当退出作用域时它不会被清除,只是未定义的行为来读取或修改它。

虽然在调试器的情况下,它可能会使用POISON标记填充页面,以检查越界访问,例如valgrind的memcheck。

答案 3 :(得分:1)

你不能保证编译器会对你没有使用的内存做什么。一般来说,它只是让它一个人。如果您希望初始化内存,则必须对其进行初始化。使用memset()可以将大部分内存有效地设置为零,但请确保您没有触及您不拥有的内存。

答案 4 :(得分:0)

真正的答案是“为什么会自行重置?”如果您尚未初始化内存,则根据定义它处于未定义状态。 (在第一次运行时它可能是十六进制零的事实并不是你可以依赖的东西。)

你肯定要冲洗它。

至于最快捷的方式,那么......

memset将是我的第一次尝试。如果那真的太慢了​​我可能会创建一个相同大小的虚拟结构,用空值填充THAT并在本地顶部做一个memcpy。这很难看,但我不指望你会得到更快的东西。