Frage

Ich habe versucht, ein sehr minimalistisches Gedächtnis zu bauen lesen Bibliothek einige unsigned ints aus ihm zu lesen. Aber ich laufe in eine „Heapbeschädigung GEFUNDEN“ Fehlermeldung, wenn die ReadUnsignedInt Methode zurückkehren will.

  

Heapbeschädigung GEFUNDEN. CRT festgestellt, dass die Anwendung in dem Speicher nach Ende des Puffers geschrieben.

Wie ich gelesen habe, ist dies die Ursache sein kann, wenn sie versuchen, löschen etwas zu verdoppeln. Dies kann durch einen falschen Gebrauch des std::tr1::shared_ptr verursacht werden, aber ich kann nicht feststellen, was ich falsch mit ihnen tue. Code ist wie folgt (Fehler ausgelassen Abwicklung):

unsigned int Memory::ReadUnsignedInt (unsigned int address) const {
    std::tr1::shared_ptr<byte> bytes = 
        this->ReadBytes(address, sizeof(unsigned int));
    return *((int*)bytes.get());
    // correct value (how to improve this ugly piece of code?)
}

std::tr1::shared_ptr<byte> Memory::ReadBytes (
    unsigned int address, int numberOfBytes) const
{
    std::tr1::shared_ptr<byte> pBuffer(new byte(numberOfBytes));
    ReadProcessMemory(m_hProcess.get(), (LPCVOID)address, 
        pBuffer.get(), numberOfBytes * sizeof(byte), NULL))
    return pBuffer;
}
War es hilfreich?

Lösung

Michael und Naveen haben beide die gleichen großen Fehler im Code gefunden, aber nicht der einzige Fehler.

shared_ptr das Spitz an Objekt delete, wenn der Referenzzähler auf Null geht.

Diese Mittel können Sie nur geben es durch new zugeordneten Objekte -. Nicht new[]

Vielleicht möchten Sie shared_ptr<vector<byte> > verwenden oder boost::shared_array<byte> statt.

Andere Tipps

Die Frage ist:

new byte(numberOfBytes)

Diese ordnet ein einzelnes Byte mit einem Wert von numberOfBytes.

Sie möchten tun:

new byte[numberOfBytes]    

Welche lange ein Array von Bytes numberOfBytes zuordnet.

Aber da du dich nur 4 Bytes wissen lesen, warum überhaupt Speicher plagen die Zuteilung? Übergeben Sie einfach die Adresse eines unsigned int auf dem Stapel.

Die grundlegenden Probleme mit Ihrem Code wurde bereits hingewiesen. Betrachtet man es, ich frage mich, links, warum Sie einen shared_ptr hier überhaupt aber, verwenden würde. Wenn ich es taten, würde ich wahrscheinlich so etwas wie diese verwenden:

unsigned Memory::ReadUnsignedInt(unsigned address) { 
    unsigned ret;
    ReadProcessMemory(m_hProcess.get(), (void *)address, &ret, sizeof(ret), NULL);
    return ret;
}

std::vector<char> Memory::ReadBytes(unsigned address, int num) { 
    std::vector<char> ret(num);
    ReadProcessMemory(m_hProcess.get(), (void *)address, &ret[0], num, NULL);
    return ret;
}

Dann wieder, statt readUnsignedInt, ich versuche sein würde, eine Vorlage zu verwenden:

template <class T>
T Memory::Read(unsigned address) { 
    T ret;
    ReadProcessMemory(m_hProcess.get(), (void*)address, &ret, sizeof(ret), NULL);
    return ret;
}

Da Sie keine Parameter übergeben, von dem sie den Typ für die Template-Parameter ableiten kann, dann würden Sie immer explizit angeben:

int x = Read<int>(wherever);
char a = Read<char>(wherever);

Die Alternative wäre, das Ziel als Parameter zu übergeben:

template <class T>
Memory::Read(unsigned address, T &t) { 
    ReadProcessMemory(my_hProcess.get(), (void *)address, &t, sizeof(t), NULL);
};

, welche würden Sie verwenden wie:

Read(wherever, some_int);
Read(somewhere, some_long);

und so weiter.

Wenn Sie über die Ineffizienz Sorgen machen einen Vektors von char Rückkehr, sollten Sie wahrscheinlich nicht - VC ++ (wie die meisten anderen halbwegs aktuellen Compiler) hat, was eine „benannte Rückgabewert Optimierung“ genannt wird, was bedeuten, in einer Situation, wie diesen, gibt sie einen versteckten Hinweis auf den Vektor Sie das Ergebnis, und Readbytes vergeben wird, dass die Daten deponieren verwenden, wo es wird direkt auf jeden Fall am Ende. Für diese Angelegenheit mit jeder vernünftigen Optimierung überhaupt eingeschaltet, Readbytes wird mit ziemlicher Sicherheit als Inline-Funktion am Ende, so beteiligte nichts wird wirklich „bestanden“ oder „zurück“ überhaupt.

Auf der anderen Seite, dieser Code nicht besonders gut mit älteren Compiler arbeiten - und mit alt genug, um Compiler, die Versionen mit Elemente Template-Funktionen werden wahrscheinlich nicht einmal kompilieren. Solange Sie einen einigermaßen aktuellen Compiler verwenden, jedoch soll das Leben gut sein.

Ich glaube, new byte(numberOfBytes) new byte[numberOfBytes] sein sollte. Sonst hätte man nur ein Byte zugeordnet. Nur um die Antwort zu vervollständigen, wie @ephemient angezeigt Sie nicht Shared_ptr hier verwenden können, da es eine delete tun, wo, wie Sie delete[] tun sollten. Wenn nicht, wie dies geschieht, wird das Verhalten nicht definiert werden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top