【问题标题】:Freeing main program memory from within a dll crushes in Visual studio 2010在 Visual Studio 2010 中从 dll 中释放主程序内存崩溃
【发布时间】:2011-05-21 06:33:57
【问题描述】:

我在使用 gcc 编译器在 C 中编写 .dll 文件时遇到了一个奇怪的问题,然后尝试通过 MSVC 和 Visual Studio 使用它。 .dll 编译正确,并被使用 gcc 编译和链接的测试程序正确使用。 但是当我尝试在 Visual Studio 中使用 .dll 时,我得到了一个奇怪的运行时迷恋。我已经确定了这个问题,希望您能就为什么会发生这种情况提供意见。

在测试程序中,我们有一个函数分配一个缓冲区,以某种方式填充它(取决于用户),然后返回缓冲区。用户必须自己实现它。如下所示:

float* decode(void* data, int dataSize, int par1, int par2,int par3)
{ 

    //allocate the memory for the data
    float* d =  (float*)malloc(sizeof(float)*dataSize);

    //do something to populate the data here

    //return data
     return d;
}

该 dll 有两个函数,它们实际上采用指向该 use-rmade 函数的函数指针并使用它来获取该 float* 缓冲区。然后 .dll 使用此函数创建和使用数据,并在使用后释放它们。

如下所示:

void DLL_Func(void* data,unsigned int inputPN,float* (*decode)(void*,int,int,int,int))
{

    //use the user-made decode function
    float* nData = (*decode)(data,inputPN,par1,par2,par3);

    //do stuff here

    //before returning free the data buffer since it is no longer needed
    free(nData) //<--- Crushes the program only in Visual Studio
 }

好吧,我将问题隔离在 free() 中。如果我从 gcc 编译的程序中使用我的 dll,但 MSVC 编译的程序在此时崩溃并给出这个:

 Unhandled exception at 0x7714e1fe in vstudiotest.exe: 0xC0000005: Access violation reading location 0x1e6dca5e.

我猜这意味着对于 MSVC 编译器,我的 dll 所做的事情是被禁止的。这只是 MSVC 的一些怪癖,还是 GCC 也应该粉碎但不会并且将来会回来并用这个问题折磨我?

当然,解决方案是以某种方式更改它,以便用户也释放缓冲区而不是 .dll,但我想先了解这种情况发生的原因。

【问题讨论】:

    标签: c visual-studio-2010 dll gcc


    【解决方案1】:

    必须使用相同的 CRT 分配和释放内存。这意味着通常您应该尝试在分配内存的同一模块中释放内存,以避免这些类型的问题。如果这不可能,您必须链接到相同版本的 CRT。

    如果您尝试链接到不同版本的 MS CRT,MSVC 会报错,但我猜您正在链接到 MSVC 不知道的其他版本。

    【讨论】:

    • 如果你需要在你的库中分配内存并在你的程序中释放它(反之亦然),你可以要求程序提供指向其mallocreallocfree的函数指针在初始化库时(或至少在调用使用它们的函数之前)。即使您不需要 malloc 和 free 在不同的模块中发生,这实际上也是一个好主意,因为它(例如)允许使用自定义分配器的程序让您的库也使用该分配器。
    • 感谢 Yaur 和 DavidX 的 cmets。是的,我想你是对的。我怀疑。在这种情况下,我只是确保内存在 dll 中实例化并在 dll 中释放,所以现在我很安全。但在没有其他选择的情况下,David X 的想法非常好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-25
    相关资源
    最近更新 更多