【问题标题】:operator "new" returning a non-local heap pointer for only one class?运算符“new”仅返回一个类的非本地堆指针?
【发布时间】:2011-02-18 10:11:52
【问题描述】:

语言:C++

平台:Windows Server 2003

我有一个调用 DLL 的 exe。

编辑: (exe 没有做任何事情,它调用了一些全局函数,这些函数在 DLL 中完成与 DLL 相关的所有事情。它没有明确地new任何 DLL 类)

我在 DLL 中为 class A 分配(new)内存,它返回给我一个非本地堆指针

我尝试new DLL 中的其他类(在 DLL 中),“new”为它们返回一个有效的堆指针,它唯一的 Class A 是没有被正确分配。

我在 Windows 上并通过此函数调用验证堆:

编辑:

 ClassA* pA = new ClassA(); 

 _CrtIsValidHeapPointer ( (const void *) pA )

我很困惑为什么这只发生在 new-ing Class A 而没有其他类?

(所有本机代码)

最终编辑:
结果证明这是一个糟糕的构建。无法让它在新版本中重现...浪费了 5 天时间:'(

【问题讨论】:

  • 非常有趣的问题; A 类是导出的,其他类不是吗?
  • 您必须向我们展示 A 类的链接,即它是 DLL 内部类吗?另外,请出示声明。
  • @DeadMG,链接是什么意思?你想看看我如何链接那个 DLL 吗?

标签: c++ windows pointers heap-memory


【解决方案1】:

也许这个类声明了它自己的操作符 new 从某个神秘位置获取存储空间?

例如该课程的作者可能写道:

class MyClass {
   public:
     void * operator new (size_t amt);
     void operator delete(void *);
};

然后他们的 operator new 击败你的 operator new。

该文件或 DLL 是使用 /MTd 构建的,而可执行文件使用 /MD。

【讨论】:

  • 不,我没有重载分配器。
【解决方案2】:

如果Class A 覆盖operator new,则可以在DLL 的C 运行时副本中分配该类的内存。这将导致_CrtIsValidHeapPointer 返回false - 因为您的 版本的C 运行时库使用的堆与DLL 中的堆不同。

_CrtIsValidHeapPointer 返回的值无论如何通常都不可靠(当然,即使它可能返回 TRUE,也不一定意味着您可以使用该指针)。你为什么要这样做?

【讨论】:

  • 谢谢 : ) 有帮助,但事实并非如此。为什么它不可靠,确定堆指针是否在本地堆中的另一种方法是什么?我尝试使用 windbg 做同样的事情并检查指针是否在本地堆的范围内但没有足够的技能,而 Windbg 一点也不直观。
  • 将您的 DLL 和您的应用程序与 C 运行时库 DLL 链接起来 - 这样它们都将使用相同的堆。
【解决方案3】:

仅从 DLL 中导出全局函数,并仅通过 v-tables 调用导出的函数。您的问题只是由于尝试导出整个类而引起的众多问题之一。 DLL 与 .so 库不同。

编辑:由于现在的问题表明该类未导出,但所有这些都在单个 DLL 中观察到,这将表明其他可能的原因。

是否正在测试从new 返回的相同指针,或者它可能是指向基本子对象的指针?分配是使用new 还是new []?其中任何一个都可能导致指针指向堆块的中间而不是开始。

【讨论】:

  • 好建议。如果您真的小心并知道自己在做什么,则可以导出整个类,但这通常不是一个好主意...
  • 本,分配实际上是在 DLL 中进行的,而不是在 exe 中分配 DLL 类,让我编辑它(我弄得很混乱)
  • 是否也从 DLL 内部调用了 _CrtIsValidHeapPointer
  • 是的,就在我做了一个新的之后,没有指针指向它自己的类(没有父级,没有切片)。
猜你喜欢
  • 2014-12-24
  • 1970-01-01
  • 1970-01-01
  • 2016-02-12
  • 2015-08-12
  • 1970-01-01
  • 2015-08-31
  • 2019-04-11
  • 2014-08-02
相关资源
最近更新 更多