使用LLVM编译器编译以下代码时,无法正常运行。(它不会增加。)当使用GCC 4.2编译时,它可以正确运行。这是一个错误的LLVM编译器?
#include <stdio.h>
#include <string.h>
void BytesFromHexString(unsigned char *data, const char *string) {
printf("bytes:%s:", string);
int len = (int)strlen(string);
for (int i=0; i<len; i+=2) {
unsigned char x;
sscanf((char *)(string + i), "%02x", &x);
printf("%02x", x);
data[i] = x;
}
printf("n");
}
int main (int argc, const char * argv[])
{
// insert code here...
unsigned char data[64];
BytesFromHexString(data, "4d4f5cb093fc2d3d6b4120658c2d08b51b3846a39b51b663e7284478570bcef9");
return 0;
}
对于sscanf
,您将使用%2x
而不是%02x
。此外,%2x
表示将传递一个额外的int*
参数。但是你要通过unsigned char*
考试。最后,sscanf
接受const char*
作为第一个实参,因此不需要进行强制转换。
试试吧:
int x;
sscanf((string + i), "%2x", &x);
EDIT:澄清为什么这个变化解决了这个问题:在你的代码中,sscanf
试图在只能容纳sizeof(unsigned char)
字节的内存位置(&x
)中写入sizeof(int)
字节。1字节)。所以,你覆盖了一定数量的内存。这个被覆盖的内存很可能是i
变量的一部分。
从编译器的角度来看,这段代码表现不同的原因是gcc和llvm(或任何其他编译器)可能以不同的方式布局堆栈。在此之前,您可能只是在堆栈上添加了本示例中不需要的其他东西,但是对于llvm编译器的不同布局,您正在添加一些更有用的东西。
这是在调试问题时使用堆栈保护的另一个很好的理由(-fstack- protection -all/-fstack-protector)。它可以帮助解决这些问题。