在一个RTOS中,我正在调试一个问题,即当程序发送一个8位值(让它称之为'Int8 rogue_int')到一个函数时,程序正在崩溃一个点(让我们称它为'Infected(Int16) )')其定义是将该变量作为16位变量。在进入最后一个函数Infected(..)之前,'rogue_int'的值是正确的,但是一旦它进入Infected(..)fn它就会有一些垃圾值并且它会命中一个断言。通常我的想法是将8位转换为16位变量应该不会导致任何问题,但是在我之间找不到任何其他问题可能会破坏静态内存。
我已经考虑了很多,并且我提出了一些理论,因为这是在一段时间之后击中断言(比如说2-3小时的执行)所以最初静态存储器很好而且干净并且没有太多增长到堆但是它在8位到16位的过程中增长,从实数no(这里是rogue_int)需要8位,但它需要额外的8位内存块,这些内存块只是分配给这个变量使其成为16位。这个新添加的8位可能已损坏,这可能会导致完全无效。
我的问题是,上面的第二段是否对C ++专家有意义?铸造8到16是否总是安全的(我认为它总是安全的,这就是为什么我没有提交我的想法更高)?如果你认为我错了,请建议可能导致这个问题的替代方案。 (断言总是只在功能'感染(..)'中的某一点被击中......不是任何其他地方)
答案 0 :(得分:2)
我不是C ++专家,但你所描述的内容没有任何意义。从8位类型转换为16位类型不会导致未初始化的内存被合并到该值中 - 此类型的upcast具有窄的,严格指定的语义,并且编译器不能仅仅获取额外的相邻字节并将其添加到您的价值中。
您所描述的内容听起来像是程序其他部分的缓冲区溢出。我建议使用像valgrind(Linux)或AppVerifier(Windows)这样的验证工具来检查你的内存访问,并从源头找到缓冲区溢出。
答案 1 :(得分:1)
将整数转换为更大的整数始终是安全的。
听起来你的程序有一个堆栈损坏问题发生在覆盖你的函数参数值的地方。
你的第二段有点意义,因为这种错误的一个潜在原因是堆栈和堆之间的冲突(即内存不足),但你所表达的逻辑基本上是错误的。 Infected
函数的参数是参数的副本。当你调用Infected(rogue_int)
时,系统没有在运行时将rogue_int
的分配扩展到16位,它为参数分配一个新的变量,它是16位宽,然后复制值其中包含8位rogue_int
。参数rogue_int
本身的值和分配不会被修改,所以肯定不是rogue_int
将另一个未初始化的8位添加到其末尾的情况。