title: Is it possible to ignore an Error 487 (ERROR_INVALID_ADDRESS) for UnMapViewOFFile()?
body: <p>Good afternoon, We are trying to build a prototype of Memory Mapped File Caching program for use by Windows and Linux 32 bit applications. Every time we run the prototype we get an Error 487(Error Invalid Address) when we try call UnMapViewOfFile to unmap a a cached memory mapped file region. We think this is happening because we trying a unmap a previouslu unmapped region. We were wondering if it is possible to ignore this error message.</p>
  
  <p>We try our best to make sure that every call to MapViewOfFile is matched by an UnMapViewOfFile in the following way, Every time we call MapViewOfFile , we use the following code:  </p>
  
  <pre><code>std::deque&lt;Range&gt; ranges_type;
  
  std::multimap&lt;char *,Range&gt; 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)));
  </code></pre>
  
  <p>Everytime we unmap a memory mapped file region, we use the following excerpt:</p>
  
  <pre><code>typedef std::multimap&lt;char *,Range&gt;::const_iterator I;
  numerased = 0;
  std::pair&lt;I,I&gt; b = mmultimap.equal_range(TmpPrevMapPtr);
  for (I i=b.first; i != b.second; ++i){ 
      std::dequeue&lt;Range&gt;::iterator iter;
      iter = std::lower_bound(ranges_type.begin(),
                              ranges_type.end(),
                              i-&gt;second);
      if (iter != ranges_type.end() &amp;&amp; !(i-&gt;second &lt; *iter)){
          ranges_type.erase(iter);
          numerased++;
      }
  }
  
  erasecount = mmultimap.erase(TmpPrevMapPtr);
  retval = UnmapViewOfFile(TmpPrevMapPtr);
  if (retval == 0){
      DWORD lasterr = GetLastError();
      ErrorMessage(lasterr);
  }
  </code></pre>
  
  <p>The class Range looks like this:</p>
  
  <pre><code>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&amp; r):
  
      bool operator==(const Range&amp; rhs) const{
          return (mLow &lt;= rhs.mLow &amp;&amp; mHigh &gt;= rhs.mHigh);
      }
      bool operator&lt;(const Range&amp; rhs) const{
          return mHigh &lt; rhs.mHigh;      
      } 
  
  public:
      int mLow;   
      int mHigh; 
      char* mPtr;
      char* mMapPtr;
      int mStamp;
      int mMappedLength;
  }; // class Range 
  </code></pre>
  
  <p>Thank you for reading this post.</p>