是否可以忽略UnMapViewOFFile()的错误487(ERROR_INVALID_ADDRESS)?

下午好,我们正在尝试构build一个由Windows和Linux 32位应用程序使用的内存映射文件caching程序的原型。 每当我们运行原型时,当我们尝试调用UnMapViewOfFile来取消映射一个caching的内存映射文件区域时,我们会得到一个错误487(错误无效地址)。 我们认为这是因为我们试图取消映射前一个未映射的区域。 我们想知道是否可以忽略这个错误信息。

我们尽量确保每次调用MapViewOfFile都通过一个UnMapViewOfFile进行匹配,每次调用MapViewOfFile时,我们使用下面的代码:

std::deque<Range> ranges_type; std::multimap<char *,Range> mmultimap; MapPtr = (char*)::MapViewOfFile(hMapping, FILE_MAP_WRITE | FILE_MAP_READ, 0, baseoff, mappedlength); if (MapPtr == 0){ DWORD lasterr = GetLastError(); ErrorMessage(lasterr); } ranges_type.insert(RangeDeque::value_type( PreviousNCopy, PreviousN, adjustedptr + n, MapPtr, TimeStamp, mappedlength)); mmultimap.insert(RangeMultiMap::value_type( MapPtr, Range(PreviousNCopy, PreviousN, adjustedptr + n, MapPtr, TimeStamp, mappedlength))); 

每次我们取消映射内存映射文件区域时,我们使用以下摘录:

 typedef std::multimap<char *,Range>::const_iterator I; numerased = 0; std::pair<I,I> b = mmultimap.equal_range(TmpPrevMapPtr); for (I i=b.first; i != b.second; ++i){ std::dequeue<Range>::iterator iter; iter = std::lower_bound(ranges_type.begin(), ranges_type.end(), i->second); if (iter != ranges_type.end() && !(i->second < *iter)){ ranges_type.erase(iter); numerased++; } } erasecount = mmultimap.erase(TmpPrevMapPtr); retval = UnmapViewOfFile(TmpPrevMapPtr); if (retval == 0){ DWORD lasterr = GetLastError(); ErrorMessage(lasterr); } 

类的范围如下所示:

 class Range { public: explicit Range(int item){ mLow = item; mHigh = item; mPtr = 0; mMapPtr = 0; mStamp = 0; mMappedLength = 0; } Range(int low, int high, char* ptr = 0,char* mapptr = 0, int stamp = 0, int currMappedLength = 0){ mLow = low; mHigh = high; mPtr = ptr; mMapPtr = mapptr; mStamp = stamp; mMappedLength = currMappedLength; } Range(const Range& r): bool operator==(const Range& rhs) const{ return (mLow <= rhs.mLow && mHigh >= rhs.mHigh); } bool operator<(const Range& rhs) const{ return mHigh < rhs.mHigh; } public: int mLow; int mHigh; char* mPtr; char* mMapPtr; int mStamp; int mMappedLength; }; // class Range 

感谢您阅读这篇文章。

Solutions Collecting From Web of "是否可以忽略UnMapViewOFFile()的错误487(ERROR_INVALID_ADDRESS)?"

我们试图取消映射previouslu未映射的区域

这是一个错误,期限。 您通过修复错误来“忽略”错误。

另外,只要用if测试就可以忽略它。 Win32函数告诉你有一个错误需要修复,但是如果你想忽略它告诉你的东西,当然没有人会阻止你这样做。

您需要修复导致内存区域未被映射两次的潜在错误。 毕竟这是考虑到的:

  • 在地址0x42000000处映射内存区域(称为A)
  • 您在0x42000000处取消映射A.
  • 您在相同的地址0x42000000处映射内存B的区域
  • 您在0x42000000处双击取消映射A – 仅此时间B未映射
  • 您尝试访问B,并崩溃。

你需要弄清楚你在哪里解决这个问题,然后解决这个问题,或者最终会发生这样的事情。 如果你隐藏了这个错误,那只会让这个更难以调试。

现在,您的会计很适合调试目的,但并不能解决问题的根源。 你没有保持良好的跟踪你的内存映射。 您不可能对已发布的代码中的一小部分进行更多的评论,但是您应该查看确定何时将映射/取消映射为您需要修复的代码; 当它太迟时,不要试图压制双重释放。 毕竟,如果你是双释放这个内存映射,这是否意味着你的代码认为它仍然映射? 在这种情况下什么是停止访问后释放的问题发生:

  • 地图A在0x42000000
  • Unmap A在0x42000000
  • 访问A(崩溃!)
  • 尝试在0x42000000(未达到,由于崩溃)双重取消映射A,

要么:

  • 在地址0x42000000处映射内存区域(称为A)
  • 您在0x42000000处取消映射A.
  • 您在相同的地址0x42000000处映射内存B的区域
  • 思维A仍然映射,你访问内存在0x42000000和访问B代替。 混乱! 或者可能是数据损坏!