struct Data {
int a;
std::string b;
float c;
};
std::string* allocateDataAndGetString() {
Data* dataPtr(someAllocator.allocate<Data>());
return &dataPtr.b;
}
Data* getBaseDataPtrFromString(std::string* mStringMember) {
// ???
}
int main() {
std::string* stringPtr(allocateDataAndGetString());
Data* dataPtr(getBaseDataPtrFromString
}
I have a Data
instance allocated on the heap, and a pointer to its std::string b;
member. How do I get the base address of the Data
instance the string is a member of, taking into account offsets and padding, in a standard way?
I've tried subtracting sizeof(int)
and std::offsetof(Data, std::string)
from the std::string*
pointer, but I couldn't get it to work.
If you are sure that some
ptr
is in fact the address of somes->b
(which is not always true) you might try to use offsetof:BTW, GCC has a builtin_offsetof to help implementing the
offsetof
macro (notably in more general cases than those required by the standard). See this question.offsetof
gives the offset in chars, so you need to cast tomStringMember
tochar *
before doing the pointer arithmetic.offsetof
only works on standard-layout types.There is a trick you might be able to use and does not require a standard layout:
static_cast
knows how to get to a more derived object from a pointer to one of its bases.Use
offsetof
from<cstddef>
, but beware it is only defined on standard-layout types (Live at Coliru):offsetof
is detailed in C++11 18.2/4:and C99 (N1256) 7.17/3:
The "restricted set of type arguments in this International Standard" in the C++ standard is there to draw your attention to the fact that
offsetof
is more restrictive than is the case for the C standard.