我写了一个函数,比如:
void func1(char chx[], int y)
{
int wsn = 0;
wsn = *(int *) (&chx[2]);
if (wsn == 0) {
...
}
}编译器工作良好,没有警告,没有错误。但是,当代码运行时,它似乎得到了一个疯狂的指针。密码崩溃了。但是,下面这样的代码工作得很好:
wsn = (chx[5]<< 24) + (chx[4] << 16) + (chx[3] << 8) + chx[2];不知道它为什么坠毁了
发布于 2014-11-09 03:10:48
正如我在一个评论中对这个问题所观察到的,如果您传递一个对齐错误的地址并试图将其视为一个int *,一些机器就不喜欢它。例如,许多RISC机器要求4字节数量的地址在4字节边界上对齐,但任意char *不一定对齐。如果您得到的是SIGBUS错误,而不是SIGSEGV错误,这通常是故障的强烈指示。
由于瑞萨站点显着地提到了'RISC‘,并且维基百科肯定了这一点,我确信您的问题是,传递给func1()的地址对齐得不够好,&chx[2]不能作为一个4字节(大概) int *有效。
执行字节操作的代码可以工作,因为它只需要对字节对齐数据,并且字节寻址机器上的所有数据都是字节对齐的。
您可以考虑使用:
void func1(char chx[], int y)
{
int wsn = 0;
int *ip = (int *)&chx[2];
if ((uintptr_t)ip & 0x3 == 0)
wsn = *ip;
else
wsn = (chx[5]<< 24) + (chx[4] << 16) + (chx[3] << 8) + chx[2];
if (wsn == 0)
{
…
}
}但是,无论如何,对shift表达式也可以做得很好。不过,有一件事值得注意:这些+运算符可能应该是|运算符,特别是如果普通char是有符号类型的话。如果它按原样工作,那么普通的char可能是一个无符号类型。这两者都是标准C所允许的,但它必须被记录在案。
https://stackoverflow.com/questions/26824346
复制相似问题