当您拨打C malloc
时,是否可以保证前几个低位将是什么?如果您正在为动态语言编写编译器/解释器但希望拥有bbbbbbbb bbbbbbbb . . . bbbbbbb1
形式的fixnums(其中b有点)和形式为bbbbbbbb bbbbbbbb . . . bbbbbbb0
的指针(反之亦然),则有什么方法可以保证malloc
会返回符合这种方案的指针吗?
我应该只分配比我需要多两个字节,如果需要,将返回值增加1以适应位方案,并将malloc
返回的实际指针存储在第二个字节中,这样我就知道了什么到free
?
我可以假设malloc
将返回一个零指针作为最后一位吗?我可以假设x86末尾有两个零位,而x64最后会有四个零位吗?
答案 0 :(得分:9)
您可以自己确保,但更好的方法是使用类似posix_memalign的内容。
如果你想自己做,你需要分配内存并跟踪原始指针。类似的东西(假设您需要16字节对齐,可以是通用的,未经测试):
void* my_aligned_malloc16(size_t sz) { void* p = malloc(sz + 15 + 16); // 15 to ensure alignment, 16 for payload if (!p) return NULL; size_t aligned_addr = ((size_t)p + 15) & (~15); void* aligned_ptr = (void*) aligned_addr; memcpy(aligned_ptr, &p, sizeof(void*)); // save original pointer as payload return (void*)(aligned_addr + 16); // return aligned address past payload } void my_aligned_free16(void* ptr){ void** original_pointer = (void**)( ((size_t)ptr) - 16 ); free(*original_pointer); }
正如您所看到的那样相当丑陋,所以更喜欢使用像posix_memalign
这样的东西。您的运行时可能具有类似的功能,如果该运行时不可用,例如使用MSVC时memalign
(感谢@R ..)或_aligned_malloc。
答案 1 :(得分:3)
对于任何数据类型,都保证Malloc返回一个具有正确对齐的指针,在某些体系结构上将是四字节边界,而在其他体系结构上可能是八。但是,您可以想象一个对齐的环境。 C库将在某个地方有一个宏,它将告诉你实际的舍入是什么。
答案 2 :(得分:3)
我的回答可能略显偏离主题,但我的驾驶舱警报就像疯了一样 - “拉起来!拉起来!”
这个方案听起来过于依赖于HW架构以及编译器和C库的深层实现细节。 C允许人们达到这个级别的细节位和字节,并查看对象模式和对象的对齐,以便对设备驱动程序等进行编码。另一方面,您正在构建一个高级实体,一个解释器和运行时。 C也可以做到这一点,但你不必使用C的低级位捻功能;恕我直言,你应该避免这样做。在那里,做到了,脚上有洞来展示它。
如果您成功创建了解释器,将想要将其移植到不同的平台,其中有关位表示和对齐的规则可能有所不同,可能是根本不同的。提出一种不依赖于这种棘手的位操作和隐藏的设计将有助于您在未来发展。
-k