如果我new
在我的库中使用关键字(它的构建方式与我的主应用程序不同),当我在主应用程序中删除它时delete
,是否有可能出现崩溃/错误?
这取决于.如果您正在谈论静态库,那么您可能会没问题 - 代码将在与主程序相同的上下文中运行,使用相同的C++运行时库.这意味着,new
和delete
将使用同一个堆.
如果您正在谈论共享库(DLL),那么您可能不会.DLL中运行的代码可能使用不同的C++运行时库,这意味着堆的布局将不同.DLL可能完全使用不同的堆.
delete
在DLL分配的指针上调用(在主程序中)(反之亦然)将导致(最多)立即崩溃或(最坏情况下)内存损坏,这需要一段时间才能跟踪.
你有几个选择.第一种是使用"工厂方法"模式来创建和删除这些对象:
Foo *CreateFoo(); void DeleteFoo(Foo *p);
这些应该不是在头文件来实现.
或者,您可以Destroy
在对象上定义方法:
class Foo { ~Foo(); public: virtual void Destroy(); };
...再次,不要在头文件中实现这一点.你这样实现它:
void Foo::Destroy() { delete this; // don't do anything that accesses this object past this point. }
请注意,Foo的析构函数是私有的,因此您必须调用Foo::Destroy
.
Microsoft COM做了类似的事情,它定义了一个Release
方法,当它的引用计数降到零时删除该对象.
是的.特别是你看到调试/发布堆的问题是不同的,如果你的库使用了新的贴图,或者任何自定义堆你都会遇到问题.调试/发布问题是迄今为止最常见的问题.
是的你将会.一个简单的解决方案是在库中提供可以从主应用程序调用的创建和删除功能.Create函数将执行new并返回一个指针,该指针稍后将被传递到Delete函数以进行删除.
这是我在Windows上看到的一个问题.
Unixish系统不习惯强制共享库链接到同一程序中同一库的不同版本,并且所有加载的符号都是全局可见的.这意味着如果一个对象在一部分代码中分配并在另一部分中删除,则两者都使用相同的系统库来执行它.
我不得不说,Windows使用其各种C运行时DLL创建的这个问题对C程序员来说真的很烦人且不自然.看看C库; 它具有strdup等函数,malloc字符串并期望程序员在其上调用free().但是在Windows上自己的库中做同样的事情,等待爆炸.你也必须等待,因为它不会在开发过程中发生,而是在你将编译后的DLL提供给其他一些糟糕的sap之后.