在构造函数分配后更改vtable内存
Change vtable memory after constructor allocation?
这是在一次采访中问我的一个问题。。。
Is it possible to change the vtable memory locations after it's
created via constructor? If yes, is it a good idea? And how to do that?
If not, why not?
由于我对C++没有深入的了解,我的猜测是,在创建vtable之后,不可能更改它!
有人能解释一下吗?
C++标准没有告诉我们必须如何实现动态调度。但vtable是最常见的方式。
通常,对象的前8个字节用于存储指向vtable的指针,但前提是对象至少有1个虚拟函数(否则我们可以将这8个字节保存为其他函数)。并且在运行时不可能更改vtable中的记录。
但是您有类似memset或memcpy的函数,可以做任何您想做的事情(更改vtable指针)。
代码示例:
#include <bits/stdc++.h>
class A {
public:
virtual void f() {
std::cout << "A::f()" << std::endl;
}
virtual void g() {
std::cout << "A::g()" << std::endl;
}
};
class B {
public:
virtual void f() {
std::cout << "B::f()" << std::endl;
}
virtual void g() {
std::cout << "B::g()" << std::endl;
}
};
int main() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(nullptr);
A * p_a = new A();
B * p_b = new B();
p_a->f();
p_a->g();
p_b->f();
p_b->g();
size_t * vptr_a = reinterpret_cast<size_t *>(p_a);
size_t * vptr_b = reinterpret_cast<size_t *>(p_b);
std::swap(*vptr_a, *vptr_b);
p_a->f();
p_a->g();
p_b->f();
p_b->g();
return 0;
}
输出:
A::f()
A::g()
B::f()
B::g()
B::f()
B::g()
A::f()
A::g()
https://ideone.com/CEkkmN
当然,所有这些操作都是射中自己脚的方法。
对这个问题的正确回答很简单:这个问题无法回答。这个问题谈到了"vtable内存位置",然后继续到"通过构造函数创建之后"。这个句子没有意义,因为"locations"是复数,而"it"只能指单数。
现在,如果您对使用vtable指针的典型C++实现有疑问,请随时提问。我也会考虑阅读《C++的设计与进化》,它包含了一堆背景信息,供那些想了解C++是如何工作的以及为什么工作的人使用。
相关文章:
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 类型总是使用其大小存储在内存中吗
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 在构造函数分配后更改vtable内存