我的意思是在struct \ memory中给变量指针,然后将它赋给某个函数,它会给我指向struct \ memory开头的指针。 有一个功能吗?
要理解这个问题:
char* ptr=((char*)malloc(12))+3;
//MemStart(ptr) == ptr-3
MemStart
将会在代码中提供该结果。
答案 0 :(得分:3)
除非存在特定于该结构在内存中的表示(例如它始终以字节0xff,0xff开头),否则无法确定特定结构或数组的起始位置。现代架构是Von Neuman机器,意味着记忆没有固有的意义。
请注意,许多体系结构都存在对齐问题或优化,这意味着结构或数组可能需要从16位,32位或64位字边界开始,但这些都是特定于体系结构的。
[编辑:添加以下内容]
库可能会在分配的内存块的开头或结尾引入guard bytes或用已知常量填充内存以查找缓冲区溢出或错误指针。但是,这些通常在发布模式中被省略,即使它们存在,也可能是有效数据。
您可以检查内存分配表以查找动态分配的内存,但是可以在堆栈而不是堆上分配数组/结构。此外,如果您在阵列中有结构会发生什么?它返回了哪个值?如果你想将它限制在动态分配的内存中你想要只分配内存的开始,那么Basile有一个很好的答案。
答案 1 :(得分:2)
大多数malloc
实现都没有提供你想要的东西(动态分配块的起始地址,给定一些内部指针)。标准不需要这样的东西。所以你可能想要使用指向base和offset的指针(可能将它们包含在一些C ++ class fat_pointer
中,operator*
和operator->
给出指针等的幻觉等等。) p>
您当然可以重新实现自己的malloc
以上操作系统内存段分配(即Linux或Posix上的mmap(2))和解除分配munmap(2)
原始系统调用。
您也可以拥有专门的分配器;它可能会使用posix_memalign为您的区域分配一个大的二次幂对齐(例如256或4096字节),然后在指针的intptr_t
强制转换上使用位操作。
请注意,实现任何严重的内存分配器意味着关心操作系统和体系结构的不可移植的细节(对齐,...)。
您也可以使用Boehm's conservative garbage collector,即使用GC_malloc
代替malloc
(并且不要打扰GC_free
您的动态数据);然后你有GC_base
函数,它完全符合你的要求:
/* Return a pointer to the base (lowest address) of an object given */
/* a pointer to a location within the object. */
/* I.e. map an interior pointer to the corresponding bas pointer. */
/* Note that with debugging allocation, this returns a pointer to the */
/* actual base of the object, i.e. the debug information, not to */
/* the base of the user object. */
/* Return 0 if displaced_pointer doesn't point to within a valid */
/* object. */
/* Note that a deallocated object in the garbage collected heap */
/* may be considered valid, even if it has been deallocated with */
/* GC_free. */
GC_API void * GC_base(void * displaced_pointer);
答案 2 :(得分:0)
您可以使用offsetof()
中的<cstddef>
宏:
#include <cstddef>
#include <iostream>
using namespace std;
typedef struct
{
int a;
int b;
} S;
int main()
{
S s = { 1, 2 };
cout << "address of s:" << &s << endl;
cout << "address of s.a:" << &s.a << endl;
cout << "address of s.b:" << &s.b << endl;
int* pb = &s.b;
S* ps = (S*)((char*)pb - offsetof(S, b));
cout << "ps:" << ps << endl;
return 0;
}
输出(ideone):
address of s:0xbffd266c
address of s.a:0xbffd266c
address of s.b:0xbffd2670
ps:0xbffd266c