gpt4 book ai didi

c# - free memory 不清除内存块

转载 作者:太空宇宙 更新时间:2023-11-04 00:33:42 25 4
gpt4 key购买 nike

我正在使用 DllImport 从我自己的 .net 类调用 c 包装器库中的方法。 c dll中的这个方法创建一个字符串变量,并返回字符串的指针。

类似这样的东西;

_declspec(dllexport) int ReturnString()
{
char* retval = (char *) malloc(125);
strcat(retval, "SOMETEXT");
strcat(retval, "SOMETEXT MORE");
return (int)retval;
}

然后我使用 Marshall.PtrToStringAnsi(ptr) 读取字符串。在我得到字符串的副本后,我只需调用另一个 c 方法 HeapDestroy,它位于调用 free(ptr) 的 c 包装器库中。

这是问题;最近,当它像一个魅力一样工作时,我开始出现“试图读取或写入 protected 内存区域”异常。经过更深入的分析,我想通了,我相信,虽然我为这个指针调用了 free 方法,但指针的值没有被清除,这填充了无人值守的堆,使我的 iis 工作进程抛出这个异常。顺便说一句,这是一个网站项目,在c库中调用了这个方法。

你能帮我解决这个问题吗?

当然,这是C#代码;

    [DllImport("MyCWrapper.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private extern static int ReturnString();

[DllImport("MyCWrapper.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private extern static void HeapDestroy(int ptr);

public static string GetString()
{
try
{

int i = ReturnString();
string result = String.Empty;
if (i > 0)
{
IntPtr ptr = new IntPtr(i);
result = Marshal.PtrToStringAnsi(ptr);
HeapDestroy(i);
}

return result;
}
catch (Exception e)
{
return String.Empty;
}
}

最佳答案

问题可能出在底层 C 代码上。您没有向 strcat 所依赖的字符串添加 NULL 终止符(或检查 malloc 是否返回 NULL)。在那种情况下很容易损坏内存。您可以通过执行以下操作来解决此问题。

retval[0] = '\0';
strcat(retval, "SOMETEXT");

还有一部分问题是您在系统上耍花招。最好正确编写它并让系统在正确运行的代码上工作。第一步是修复 native 代码以正确返回字符串。您需要考虑的一件事是,只有某些类型的内存可以由 CLR(HGlobal 和 CoTask 分配) native 释放。因此,让我们更改函数签名以返回 char* 并使用不同的分配器。

_declspec(dllexport) char* ReturnString()
{
char* retval = (char *) CoTaskMemAlloc(125);
retval[0] = '\0';
strcat(retval, "SOMETEXT");
strcat(retval, "SOMETEXT MORE");
return retval;
}

然后您可以使用以下 C# 签名并使用 Marshal.FreeCoTaskMem 释放 IntPtr。

[DllImport("SomeDll.dll")]
public static extern IntPtr ReturnString();

不过更好。编码时,如果 CLR 认为它需要释放内存,它将使用 FreeCoTaskMem 来这样做。这通常与字符串返回相关。由于您使用 CoTaskMemAlloc 分配了内存,因此您可以节省编码 + 释放步骤并执行以下操作

[DllImport("SomeDll.dll", CharSet=Ansi)]
public static extern String ReturnString();

关于c# - free memory 不清除内存块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1498994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com