如果我使用new关键字在我的图书馆(这是建立不同于我的主要应用程序),当我在与delete主要的应用程序删除它,是没有办法,我可能会崩溃/错误的机会吗?

有帮助吗?

解决方案

是indeedy。特别是你看问题的调试/释放堆是不同的,也如果你的库使用放置新的,或任何自定义堆你就会有问题。调试/释放问题是目前最常见的,但。

其他提示

这取决于。如果你谈论的是一个静态库,那么你很可能会确定 - 该代码将在相同的上下文中主程序运行,使用相同的C ++运行时库。这意味着,newdelete将使用相同的堆。

如果你在谈论一个共享库(一个DLL),那么你可能不会确定。在DLL中运行的代码可能会使用不同的C ++运行时库,这意味着堆的布局将是不同的。该DLL可以是完全使用不同的堆。

调用由DLL(反之亦然)分配的指针delete(主程序)会导致(最好)立即崩溃或(在最坏的情况),内存损坏那将需要一段时间来追查。

您已经有了几个选择。第一种方法是使用“工厂方法”图案创建和删除这些对象:

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::Destroy

微软COM做类似的东西,它定义了删除对象时其引用计数下降到零的Release方法。

是的,你会的。一个简单的解决方案是在你的库,可以从主应用程序调用提供创建和删除功能。创建功能将执行新并返回一个指针,稍后传递到用于删除的删除功能。

这是我只看到Windows上的问题。

在Unixish系统不使迫使共享库在同一程序内链接到不同版本的相同的库和所有加载的符号是全局可见的习惯。这意味着,如果一个物体在一个代码部分分配和另一删除,两者都使用相同的系统库做到这一点。

我不得不说,这个问题的Windows创建了它的各种C运行时的DLL实在是烦人,不自然的C程序员。看看C库;它有像的strdup确定malloc的字符串,并期望程序员就可以调用free()函数。但是,做同样的事情在Windows自己的图书馆,并只是等待爆炸。你必须等待,也因为它不会在开发过程中发生,但你给编译的DLL其他一些可怜虫之后。

旧事新之前已经覆盖了这一。他还给出了微软的主要解决方案的列表。

您说得很对,有一个问题存在,但大多数情况下,有一个比其他的答案更简单的解决方案(到目前为止)提出。您可以继续使用新的和随意删除 - 所有你需要做的就是重载new和delete为库中的每个类可能跨DLL边界使用

我个人刚刚定义一个简单的类,以提供所需的功能:

class NewDelete
{
    public:
        void *operator new (size_t size);
        void operator delete (void *memory);
        void *operator new (size_t size, void *ptr);
        void operator delete (void *memory, void *ptr);
};

只要这四个成员函数都在相同的DLL中定义,其然后从这个类派生的任何类自动是“DLL安全” - 新和删除可以正常上他们,而不必担心DLL边界使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top