尝试读取或写入受保护的内存。这通常表明其他内存已损坏

Posted

技术标签:

【中文标题】尝试读取或写入受保护的内存。这通常表明其他内存已损坏【英文标题】:Attempted to read or write protected memory. This is often an indication that other memory is corrupt 【发布时间】:2013-01-23 00:01:32 【问题描述】:

我在尝试将字符串数组从 C# 传递到 C++ 时遇到此错误。此错误有时会出现,但并非总是如此。

C# 中的声明

[DllImport(READER_DLL, 
        CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    public static extern void InstalledRooms(string[] rooms,int length);

在 C++ 中

void InstalledRooms(wchar_t const* const* values, int length);

void DetectorImpl::InstalledRooms(wchar_t const* const* values, int length)

    LogScope scope(log_, Log::Level::Full, _T("DetectorImpl::InstalledRooms"),this);
    std::vector<std::wstring> vStr(values, values + length);
    m_installedRooms=vStr;
 

它是如何从c#调用的?

//List<string> installedRooms = new List<string>();
//installedRooms.add("r1");
//installedRooms.add("r1"); etc
NativeDetectorEntryPoint.InstalledRooms(installedRooms.ToArray(),installedRooms.Count);

错误发生在

Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at MH_DetectorWrapper.NativeDetectorEntryPoint.InstalledRooms(String[] rooms, Int32 length)

任何帮助将不胜感激

【问题讨论】:

可能是您的 P/Invoke 声明应该使用 StringBuilder(但这是一个完整的猜测!): public static extern void InstalledRooms(StringBuilder[] rooms,int length); 尝试添加 [MarshalAs(UnmanagedType.LPArray)] string[] 个房间 @MatthewWatson 我不确定你是否正确,也根据这个***.com/questions/1713288/… 您需要编写代码来捕获此异常,然后转储roomslength 的内容以确定原因。 【参考方案1】:

这只是一个猜测,但由于错误是间歇性的,我认为这是与 string 数组 installedRooms 相关的内存问题。

如果您不使用Fixed 关键字标记托管对象,GC 可能随时更改对象的位置。因此,当您尝试从非托管代码访问相关内存位置时,可能会抛出错误。

您可以尝试以下方法;

List<string> installedRooms = new List<string>();
installedRooms.add("r1");
installedRooms.add("r2"); 
string[] roomsArray = installedRooms.ToArray();

fixed (char* p = roomsArray)

    NativeDetectorEntryPoint.InstalledRooms(p, roomsArray.Count);

【讨论】:

我尝试使用两个线程来模拟问题 1. 线程一循环将数组从 c# 发送到 c++。 2. 垃圾回收的第二个线程。但这从未重现错误。有没有更好的方法来重现错误,然后确定地测试解决方案。 @daryal 我无法使用您的解决方案,我收到“fixed (char* p = roomsArray)”的编译时错误。错误是:无法获取托管类型(“字符串”)的地址、大小或声明指向托管类型的指针。根据 [link]***.com/questions/2559384/… 字符串数组不能是固定类型

以上是关于尝试读取或写入受保护的内存。这通常表明其他内存已损坏的主要内容,如果未能解决你的问题,请参考以下文章

尝试读取或写入受保护的内存。这通常表明其他内存已损坏

尝试读取或写入受保护的内存。这通常表明其他内存已损坏

尝试读取或写入受保护的内存。这通常表明其他内存已损坏 DllImport

尝试读取或写入受保护的内存。这通常表明 c# 中的其他内存已损坏(访问冲突)

错误:试图读取或写入受保护的内存。这通常表明其他内存已损坏

错误“试图读取或写入受保护的内存。这通常表明其他内存已损坏。”