gpt4 book ai didi

c# - 提升指针后释放 IntPtr 分配的内存

转载 作者:行者123 更新时间:2023-11-30 04:04:04 25 4
gpt4 key购买 nike

我在 C# 中使用 IntPtr,从 C++ 项目中获取对象数组。

为此,我使用 Marshal.AllocHGlobal 方法分配了所需的内存,并将 C++ 中的完整数组复制到 ptr 中。

问题是我正在提升指针,移动到数组中的下一个对象。

我的问题是:在使用 Marshal.FreeHGlobal 方法之前,我是否必须恢复 IntPtr 的第一个值?

这是代码

public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);

DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(buffer, dirEntry);
buffer += dirEntrySize;
}

Marshal.FreeHGlobal(buffer);
return dirEntries;
}

最佳答案

您必须创建原始指针的拷贝,供以后使用。在这种情况下,它被称为电流:

    public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);

IntPtr current = buffer;

DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(current, dirEntry);
current += dirEntrySize;
}

Marshal.FreeHGlobal(buffer);
return dirEntries;
}

但是,还有另一种可能性,无需通过使用 IntPtr.Add() 使用指针的显式拷贝:

    public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);

DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(IntPtr.Add(buffer, i * dirEntrySize), dirEntry);
}

Marshal.FreeHGlobal(buffer);
return dirEntries;
}

请记住,您的代码包含潜在的内存漏洞。您应该将代码包装在 try/finally block 中。如果指针不为零,则在 finally block 中再次释放内存块:

    public List<DirEntry> getDirEntries()
{
int dirEntrySize = Marshal.SizeOf(typeof(DirEntry));
int bufferSize = 28 * dirEntrySize;
IntPtr buffer = Marshal.AllocHGlobal(bufferSize);

try
{
CppToCsharpAdapter.getDirEntries(this.myDiskPointer, buffer);

DirEntry dirEntry = new DirEntry();
List<DirEntry> dirEntries = new List<DirEntry>();
for (int i = 0; i < 28; i++)
{
Marshal.PtrToStructure(IntPtr.Add(buffer, i * dirEntrySize), dirEntry);
}
}
finally
{
if (buffer != IntPtr.Zero)
Marshal.FreeHGlobal(buffer);
}


return dirEntries;
}

关于c# - 提升指针后释放 IntPtr 分配的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23948947/

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