2011-01-14 15 views
0

私は練習としてC++で書いているメモリスキャナから一致しない結果を削除しようとしています。メモリを最初にスキャンすると、すべての結果がベクトル_resultsに格納されます。アクセス違反C++(ベクトル内の項目の削除)

その後、_resultsが再度スキャンされ、一致しなくなったアイテムが消去されます。

エラー:std::vector<T>オブジェクトがアイテムを削除した後、基礎となる配列の連続を維持するために周りの要素をシフトするためstd::vector<T>から

Unhandled exception at 0x004016f4 in .exe: 0xC0000005: Access violation reading location 0x0090c000.

// Receives data 

DWORD buffer; 

for (vector<memblock>::iterator it = MemoryScanner::_results.begin(); it != MemoryScanner::_results.end(); ++it) { 
    // Reads data from an area of memory into buffer 
    ReadProcessMemory(MemoryScanner::_hProc, (LPVOID)(*it).address, &buffer, sizeof(buffer), NULL); 

    if (value != buffer) { 
     MemoryScanner::_results.erase(it); // where the program breaks 
    } 
} 
+0

提供されたコードは、質問に答えるのに十分な、完全ではないようです。 –

+0

私は、型が無関係であると思ったのは、それが明示的に消去行を指し示しているアクセス違反だからです。 –

答えて

5

消去要素がitイテレータを無効にします。無効なイテレータを逆参照しようとして終了しないように、新しい、有効なイテレータを返しvector<T>::erase()幸い

、:

DWORD buffer; 
vector<memblock>::iterator it = MemoryScanner::_results.begin(); 
while(it != MemoryScanner::_results.end()) 
{ 
    ReadProcessMemory(MemoryScanner::_hProc, (LPVOID)(*it).address, 
     &buffer, sizeof(buffer), NULL); 
    if (value != buffer) 
    { 
     it = MemoryScanner::_results.erase(it); 
    } 
    else 
    { 
     ++it; 
    } 
} 

ベクトル

内の項目を削除する別の方法

erase-remove idiomをご利用いただきありがとうございますか?

struct RemoveNonMatches 
{ 
public: 
    RemoveNonMatches(HANDLE p, DWORD v) : proc(p) val(v) {} 

    bool operator()(const memblock& obj) 
    { 
     DWORD buffer; 
     ReadProcessMemory(proc, static_cast<LPVOID>(obj.address), 
      &buffer, sizeof(buffer), NULL); 
     return (buffer != val); 
    } 

private: 
    HANDLE proc 
    DWORD val; 
}; 

// ... 

MemoryScanner::_results.erase 
(
    std::remove_if 
    (
     MemoryScanner::_results.begin(), 
     MemoryScanner::_results.end(), 
     RemoveNonMatches(MemoryScanner::_hProc, value) 
    ), 
    MemoryScanner::_results.end() 
); 
+0

'it = MemoryScanner :: _ results.erase(it);'それを修正しませんでした –

+0

ああ、ちょうどelseステートメントを忘れました。ありがとう。 –

1

vector::eraseerase()に渡されたイテレータを無効にします。その後、それを増やそうとします。 UBが続く。

0

完全性についてstd::remove_ifバージョン、:

bool has_bad_memory_contents(const memblock& block) { 
    DWORD buffer; 
    ReadProcessMemory(
     MemoryScanner::_hProc, (LPVOID)block.address, 
     &buffer, sizeof(buffer), NULL 
    ); 
    return buffer != value; 
} 

std::vector<memblock>& r = MemoryScanner::_results; 
r.erase(std::remove_if(r.begin(), r.end(), has_bad_memory_contents), r.end()); 
関連する問題