c-字符串上的*(long*)是什么导致分段错误的



考虑以下一个或两个"数据"值:

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
//char * data = "21st Century Schizoid ManI Talk to the WindEpitaffMoonchildThe Court of the Lavender King";
char data1[93] = {'2','1','s','t',' ','C','e','n','t','u','r','y',' ','S','c','h','i','z','o','i','d',' ','M','a','n','','I',' ','T','a','l','k',
't','o',' ','t','h','e',' ','W','i','n','d','','E','p','i','t','a','p','h','','M','o','o','n','c','h','i','l','d','','T','h','e',' ','C',
'o','u','r','t',' ','o','f',' ','t','h','e',' ','C','r','i','m','s','o','n',' ','K','i','n','g',''};
char * data = data1;
void main () {
char cVar1;
int iVar3;
int iVar4;
iVar3 = 0; iVar4 = 0;
//cVar1 = *(char *)((long)iVar3 + *(long *)(data + (long)iVar4 * 8));
cVar1 = *(char*)(*(long*)data);
} 

为什么分配给cVar1会导致分段错误?我知道*(long*(有问题,因为删除它可以防止Seg Fault。

编辑:一位评论者链接了一篇帖子,认为这是一个对齐问题,但如何解决?将char数组的大小更改为96,使其大小可以被4或8整除(长数组的大小(并没有停止分段错误。许多其他铸造组合也起作用:

cVar1 = (char*)(*(long*)data):
cVar1 = *(char*)(long*)data);

例如

与其说这是对齐问题,不如说这是一个无效的指针值。

首先你有这个:

(long*)data

结果产生指向与data相同的存储器位置的long *。然后你取消引用指针:

*(long*)data

在这一点上,C标准指出这是未定义的行为。在具有更严格对齐要求的体系结构上,这可能会导致崩溃,但在具有64位long的x86机器上,您可能最终会得到一个由data的前8个字节组成的值,其中最低有效字节优先。这将产生一个值0x6e65432074733132,如果仔细观察,它是按相反顺序排列的前8个字符的ASCII代码。

现在你有了这个:

(char*)(*(long*)data)

它将值0x6e65432074733132解释为指针。然后你尝试取消引用它:

*(char*)(*(long*)data)

0x6e65432074733132几乎肯定不是一个有效的地址,所以当您试图取消引用该值时,您会得到一个segfault。

最新更新