c - 从 C# 代码访问 C 代码中分配的结构体内存

标签 c memory-leaks c#

我有一个从 C 代码分配的结构列表。我将此结构列表的指针返回给 C# 代码。最后,C# 代码使用此指针并将其编码到相应的 C# 结构列表中。 C 和 C# 代码都捆绑在一起。

我想确认在这种情况下是否存在内存损坏的可能性,或者是否存在我们丢失内存指针所指向的句柄的情况。从 C 代码分配的内存何时会被销毁。

下面是代码片段。

示例 C 代码

 typedef struct sampleData {
    int id;
    int sid;
 } SampleData; 

  SampleData* func(){
    SampleData* pd = (SampleData*) malloc(10 * sizeof(SampleData)) ;
    for(int i=0;i<10;i++){
       pd[i].id=i*10;
       pd[i].sid=i*10;
    }
    return pd;
}

示例 C# 代码

class Test
    {
    [StructLayout(LayoutKind.Sequential, Pack=1)]
        public struct TestData{

            [MarshalAs(UnmanagedType.I4)]
            public int id;
            [MarshalAs(UnmanagedType.I4)]
            public int sid;
        }

        [DllImport("sample.so", EntryPoint = "func")]
        static extern IntPtr func();

        public void collectSampleData()
        {
            IntPtr idPtr = IntPtr.Zero;
            IntPtr sidPtr = IntPtr.Zero;
            idPtr = func();

            for(int i=0;i<10;i++){

                TestData TestDataObj=new TestData();

                IntPtr currPtr = new IntPtr(idPtr.ToInt64() + ( i * Marshal.SizeOf(typeof(TestData))));

                TestDataObj = (TestData)Marshal.PtrToStructure(currPtr,typeof(TestData));

                Console.WriteLine(TestDataObj.id+" "TestDataObj.sid);

            }
        }
    }

在上面的代码中,当从 C# 端访问时,是否有可能丢失为 Sampledata 结构列表完成的内存分配句柄。因为上面的代码现在给出了正确的值。

最佳答案

按原样,托管代码不应出现内存损坏。

但是,除非您明确执行某些操作,否则非托管内 stub 本不会被释放。

“传统”API 通常使用两种方法来处理此问题:

  • 它们在调用时接受一个指针(通常带有缓冲区大小信息),并将数据存储在指针指向的内存区域中。在这种情况下,它们不会像使用 malloc() 那样分配内存,调用者负责提供缓冲区并管理内存。如果缓冲区不够大,被调用者应该返回错误。大多数 Win32 API 都是这样工作的(文件访问等)。

  • 他们提供了另一个调用来释放内存。在这种情况下,malloc()free() 都在您的外部代码中,并且托管端不会主动管理内存,但它必须在何时通知外部代码指针不再使用。请注意,COM 确实使用了引用计数的相关方法;当计数器达到 0 时,对象被释放。

关于c - 从 C# 代码访问 C 代码中分配的结构体内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53959846/

相关文章:

c# - 尝试将 SQL 中的 varbinary(MAX) 值转换为 byte[] 并在 asp 图像控件中显示

c - 我应该把 CMakeLists.txt 文件放在哪里?

c - 当我在嵌套的 for 循环中包含括号时,它无法正常运行,但当我将它们取出时,它可以正常运行;为什么是这样?

java - android/java - 当没有对实例的引用时如何得到通知

javascript - setTimeout() 如何在此代码中造成内存泄漏?

c# - 无法使用 S3 TransferutilityUploadRequest 上传文件

c# - 从 C# 调用 PHP Web 服务

c - 如何让 C 程序回复一封信并吐出其他内容?

c - 从动态数组 C 中删除元素

java - 共享库分配的 JNA 空闲内存