【问题标题】:Size of pointer to member function varies like crazy指向成员函数的指针大小疯狂地变化
【发布时间】:2015-04-13 14:06:45
【问题描述】:

遇到了一个非常微妙的问题。 得到了一个用 MS VS 2013 c++ 编译器编译的类,对于 32 位平台,大小为 4 个字节。函数指针的大小为 4 个字节。但是当这个类用同一个编译器编译但是包含到不同的项目中生成库,同样针对32位平台,那么这个类有*m_Function指针占用16个字节!当然,当我从主项目实例化这个类时,它认为该类占用 4 个字节并分配这个内存大小,而实际上它占用 16 个字节并导致内存溢出。

 class CC1
    {
    public:
        CC1();

        void (CC1:: *m_Function) ();
    };

我知道指向成员函数的大小可以变化。但问题是 - 哪个编译器设置控制这个?我不在乎它是 4 字节还是 16 字节——只需要它们相同即可。两个项目的结构成员对齐设置相同。 /vmm /vmg 选项?在两个项目的编译器设置中都没有提及它们。

顺便说一句,我尝试为 x64 目标构建,在这种情况下 sizeof *m_Function 始终是 8 个字节,来自 main 和 libray 项目。

谢谢。

【问题讨论】:

  • 您是否以相同的方式构建(IE 调试与发布)?
  • 可能不同的构建设置(对齐、调试信息等...)
  • 你想做什么要求它们是一样的?
  • @southerton 请注意此类错误,因为它们通常是由 ODR 问题引起的,因此它们很可能是 heisenbugs。仔细检查现在有效的内容以及上次签入源代码管理的内容,以检查您是否确实得到了修复,并且该错误还没有被隐藏并准备好在几周内咬你...

标签: c++ pointers visual-c++ sizeof


【解决方案1】:

See here for docs page for /vm options

如果您使用 '/vmg' 编译器选项,则指向成员函数的指针将始终为 16 个字节,因为您有效地告诉编译器它可能事先不知道大小,因此必须假设最坏的(虚拟继承!)。

如果你使用'/vmb',那么编译器在使用前必须知道结构的继承模式,这样才能使用最有效的方法——在简单继承的情况下,这是4个字节。

可能在某些项目中您设置了“/vmg”(使类为 16 个字节),而在其他项目中您没有设置(使类为 4 个字节)。

/vmb 是隐式默认值 - 检查您的编译器命令行,查找此类为 16 字节的库的 /vmg

【讨论】:

  • 我的问题与调试信息格式有关。当我将它从 /ZI 切换到 /Zi (对于被调用项目(?))时,问题消失了,lib 和 exe 项目中的指针都是 4 个字节。然后我再次尝试重现此行为设置 /ZI,但指针大小仍为 4 个字节。 (而且我的项目集中没有 /vmz 或 /vmb)。
  • 但是,我标记了您的答案,因为然后我尝试按照您的建议在 lib 上设置 /vmz 选项,并且指针的大小变成了 16 个字节。因此,如果其他人遇到这个问题,这对他来说可能是一个很好的解决方案。
猜你喜欢
  • 2012-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多