马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
Test test;
Test* tptr = &test;
std::cout << (void*)(&tptr->a) << std::endl;
std::cout << (void*)((void(*)()) * ((int*)(*((int*)&test)) + 0)) << std::endl;
第二个输出虚函数的地址是正确的。
如果这么写:std::cout << (void*)((void(*)()) * ((int*)(*((int*)tptr)) + 0)) << std::endl;
就是分段错误。
这是怎么回事?难道还要用 dynamic?
在C++中,对象的虚函数通常是通过虚函数表(vtable)来实现的。一个对象的vtable是一个函数指针的数组,其中每个函数指针对应于对象的一个虚函数。vtable的具体实现可能因编译器而异,但通常,当你创建一个对象时,编译器会自动在该对象中插入一个指向其vtable的指针。
从你的代码中,我假设 Test 是一个含有虚函数 a 的类。然后你试图手动通过对内存的操作来访问这个虚函数 a 的地址。在你的第二段代码中,你试图获取 tptr (指向 Test 对象 test 的指针)的vtable中第一个函数的地址。
关于你的问题,我认为你在第二段代码中遇到分段错误的原因可能是,你在操作指针时,不小心访问到了不应该访问的内存区域。这可能是因为你的代码假设了某种特定的内存布局或者vtable的实现,而这种假设在你的环境中并不成立。例如,你可能假设 Test 对象的第一个字节就是指向其vtable的指针,但实际上可能并不是这样。
你可能需要使用一些更复杂的技术,如RTTI(运行时类型信息)或者dynamic_cast,来安全地获取和调用虚函数的地址。但是,我建议你不要试图手动操作vtable或者内存,因为这样很容易出错,而且会使你的代码变得难以理解和维护。如果你需要调用一个对象的虚函数,你应该直接通过对象或者指向对象的指针来调用它,而不是试图手动找到这个函数在内存中的位置。
更一般地说,如果你需要在运行时获取和调用一个对象的虚函数的地址,那么你可能需要重新考虑你的设计。在大多数情况下,你应该能够通过使用正确的继承和多态来实现你需要的功能,而无需手动操作内存。如果你觉得你需要手动操作vtable,那么你可能需要寻求一种更好的解决方案。
|