一、遇到的问题
1)情景说明:
我在一个类中定义了一个全局变量a,然后在类初始化的时候给该变量赋一个初始值a=10。该变量有被其他类外部引用,但是外部引用只是使用该值,并没有修改该值。然后在一个Timer中每秒打印这个变量1次。
2)看到的现象:
该变量a期初一直输出10,在突然的某一时刻,该值变成了 0
二、我所想到的问题的原因
我看到这种现象后,脑子不加思索的就想到以下两种原因:
1)肯定有人改变变量a的值。
答案是肯定的,只是在那个类初始化的时候给变量赋一次值,其它地方均没有。
2)要么是拥有该变量的对象被销毁了,所以其值就变成0了。
答案是很明显的,自习读题目就能发现,这种现象不可能发生,因为它是一个全局变量,不属于哪一个对象。
三、真正的原因
是由于其它线程中的某个对象malloc堆内存空间时,把全局区的变量的地址给占用了。。也就是堆空间把全局变量区的部分地址给占用了。
对此,我们做了一个测试:
char mycha[1024*10]; // 声明10K的空间
double a;
init(){
a = 10;
memset(mocha,'a',1024*10);
}
timer(){
printf("%f",a);
printf("%s",mycha);
judge();
}
judge(){
if(mycha[0] != 'a'){
NSLog(@"发生了内存错误");
}
}
我们通过打印发现:
mycha后来真的不是aaa……了,它真的被改变了。由于mycha和a的位置挨着,所以a得值发生变化,肯定也是其内存地址被别人给破坏掉了。
证实:
我们可以通过watch change(Xcode中debug功能)a变量,可以发现是哪个地方把a给变了。这样就能很好的定位了。
四、结语
可能非常棘手的问题(比如就这个问题,找了整整两天)是非常低级的错误造成的。所以,写代码的时候不能犯困,不能违背编程规范。

本文描述了一起全局变量值莫名变为0的编程问题。通过分析,作者排除了变量被直接修改和对象销毁的可能性,最终发现是由于其他线程的堆内存分配导致全局变量内存被覆盖。通过调试定位,找到了问题的根源,提醒开发者注意编程规范,避免低级错误。
8837





