一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
前两天遇到了一个错误,并且这个错误是由自己一手造成,而且编译器也无法鉴别的错误。所以说,让我调试起来真是费了很大的力气,只是改了一句代码居然好了!
开发环境:VS2017 + Qt5.14.2
一般来说,我们定义的变量只要不是自增的情况下, 编译器是不会偷偷摸摸的修改数据的,那么,为什么我会说bool值的变量在运行过程中会被自动篡改呢?
前提,在程序中所有对bool类型的变量赋值的地方我都有进行日志输出,但是运行过程中莫名其妙的被修改了?
大家有没有遇到过这样的问题呢?又是怎么解决呢?
有人说是bool值不如BOOL值安全,在程序中最好使用BOOL值。是真的这样吗?
bool是占1个字节的变量,BOOL是占4个字节的变量,可以理解成简化的int类型。
在某些情况下,我们的码代码技术不严谨时,确实BOOL会比bool值安全。这就是我今天要说的问题,在运行过程中被篡改。最终导致我的bool在运行被修改。
int m_nState[6] = {0};
bool m_bOpen;
看上述两个变量的定义。没有什么奇怪之分吧!
成员变量1:声明了一个int类型的数组,大小为6,并将其初始化为0,且每个元素都为0。
成员变量2:声明了一个bool类型的变量,假设默认设置为false
单纯的看两个变量是没有任何问题的,如果你得C++学的很棒,那么在后面你是不会出现我刚刚上述说的问题。
如果你对C++的概念不是很透彻,那么请继续往下看!
在程序运行过程中,我想要对数组中的数据清空,那么该如何操作呢?
是这种形式吗m_nState[6] = {0}
猛然间一看,也发现不出什么错误来,这时候其实是越界了,但是,我们的VS编译器是不会报出任何错误的,不信的话,大家可以尝试一下。
那么,编译器不报错,就真的没关系了吗?
NO! 我们在.h中声明数组的时候,紧接着又声明了bool类型的变量,经过我们刚刚的m_nState[6] = {0}
赋值操作,会直接让我们的bool值悄悄地发生变化。不信?没关系,大家尽情的尝试,分别在赋值之前跟赋值之后打出日志来查看!
本身我们在声明的时候,数组中的数据只能存放 0-5之间,这里,你却来了个[6],那不越界就奇怪了!
越界后,为什么我们编译器是不会报错误呢?
在int类型数组后面紧跟着其他类型的变量的定义,当前变量越界后会直接篡改紧邻的变量类型。
bool值占一个字节,此时,运行的过程中,编译器就会给我们将数据修改!是不是很神奇!
但是,我们换用了BOOL作为紧邻的变量,例如下面的写法
int m_nState[6] = {0};
BOOL m_bOpen;
此时,再进行越界处理时,不会影响BOOL值的变化。
这是为什么呢? BOOL类型占了4个字节,实际上有效的是低字节,所以即使是越界,也不会改变实际的值,bool类型就不一样了,只占了1个字节,越界后直接会被篡改。
那么我们该如何对数组类型的数据进行清空呢?
memset(m_nState, 0, 6);
还需要注意一点的是,如果你得数组越界之后,此时你并没有检查出来时,只要是后面的变量有bool类型时,依旧会被篡改!
大家请记住这一点,不是bool不安全,而是我们的写法有些时候是不严谨了。
我是中国好公民st,一名C++开发程序猿~