我有以下代码(我没有写它并且它被简化为仅显示有问题的部分):
#include <stdlib.h>
typedef struct test_struct {
unsigned int foo;
char *dummy;
} test_struct;
int main()
{
test_struct *s = (test_struct *) malloc(10 * sizeof(test_struct));
s = (test_struct *)((unsigned long)s + 16);
s->foo = 1; // crash!
}
程序为10个结构分配内存(在我的平台中为10 * 24个字节)。然后,指针增加16个字节,并尝试在该位置写入数字。
我已经在4台电脑上测试了这个片段。其中两个在Windows 7 x64上运行,效果很好。另一个在lubuntu x64上运行,也按预期工作。另一个是Windows 10 x64,它崩溃了。
你能帮我理解那些线路有什么问题吗?我使用第三方图书馆来做这件事,我不知道到底发生了什么。
答案 0 :(得分:4)
s =(test_struct *)((unsigned long)s + 16);
在某些平台上long
不足以存储指针,因此请改用uintptr_t
:
s = (test_struct *)((uintptr_t)s + 16);
程序为10个结构分配内存(在我的情况下为10 * 24字节)。然后,指针增加16个字节
无论您想要实现什么,请注意结构的大小也取决于平台。不仅结构内的字段,而且填充在不同平台上也可能不同。
因此,在计算中,我们最好使用sizeof
和offsetof
代替16
这样的幻数。
答案 1 :(得分:0)
test_struct * s =(test_struct *)malloc(10 * sizeof(test_struct)); s =(test_struct *)((unsigned long)s + 16);
您的计划中有多个错误: - 1.你应该明白内存分配完全取决于操作系统。显示内存分配的原因是你可能会溢出16。 2.在s中更改地址存储后,您现在正在访问foo,这是无效的。 3.使用valgrind并检查无效。