先不多说,直接上程序:
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <cstring>
#include <map>
using namespace std;
struct test {
uint32_t a;
};
struct player_t {
std::map<uint32_t, test> a_map;
//std::map<uint32_t, test>* a_map;
uint32_t uid;
uint32_t role;
uint32_t time;
};
int main(int argc, char *argv[])
{
unsigned long off_pos = (unsigned long)(&((struct player_t*)0)->role);//offsetof()
cout<<"n="<<off_pos<<endl;
system("PAUSE");
return EXIT_SUCCESS;
}
程序中off_pos是算变量role在player_t结构中的偏移量,但用g++编译的时候报警告:
[Warning] invalid access to non-static data member `player_t::role' of NULL object
[Warning] (perhaps the `offsetof' macro was used incorrectly)
感觉编译器对这样的偏移量的计算有意见,如果换成指针形式:std::map<uint32_t, test>* a_map;就没有问题,似乎STL类型的数据无法确定内存的大小!
上网查阅文档发现以下文字:
请注意根据在 ANSI c + + 草稿使用文章,子句 18.1.5,offsetof 宏仅限于 POD 联合和 POD 结构类型。 POD 类型不能有基类。使用宏违反此限制结果中未定义的行为!
所谓POD就是plain old data,解释为:A plain old data structure (POD) is a data structure that is represented only as passive collections of field values, without using encapsulation or other object-oriented features。
也就是说POD是指C里的基本类型,例如:a built-in type, pointer, union, struct, array, or class with a trivial constructor.
而Non-POD当然就是POD的相反,可能是很复杂的类别或结构,例如STL之类。
他们的生命周期也不一样:
1.POD:和出现在记忆体的时间一样;
2.Non-POD:开始在constructor,结束在destructor。