5 Stimmen

Versuch, geschützten Speicher zu lesen oder zu schreiben, wenn Wert auf Zeiger

Ich habe diesen Code:

typedef struct {
    string fName;
    string str; 

}t;

//-------Other functions------//
void BeginTh()
{
    string arg = "yes";
    t *arglist;
    arglist = (t*)malloc(sizeof(t));
    arglist->fName = "comBomber";
    arglist->str = arg;
    _beginthread(startOver, 0, (void*)arglist);
    free(arglist);
}

Und bei 'arglist->fName = "comBomber";' bekomme ich diesen Fehler:

An unhandled exception of type 'System.AccessViolationException' occurred in <appname>

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Kann mir jemand helfen? Wie kann ich dieses Problem lösen?

Gracias.

6voto

sehe Punkte 346808

Ich schlage einen modernen C++-Stil vor:

#include <future>
#include <string>

struct arg_t {
    std::string fName;
    std::string str; 
};

int startOver(int i, arg_t args)
{
    return args.fName.size() + args.str.size() + 42;
}

int main()
{
    const std::string arg = "yes";
    arg_t args = { "comBomber", arg };
    auto worker = std::async(startOver, 0, args);
    return worker.get();
}

Siehe auf http://ideone.com/zrXcwH (es läuft nicht, weil ideone das Programm nicht unterstützt. pthread Bibliothek). Ich habe dies mit MS Visual C++ getestet.

Si arg_t sehr teuer wäre, können Sie sie einfach in den anderen Thread verschieben:

auto worker = std::async(startOver, 0, std::move(args));

5voto

juanchopanza Punkte 216358

Ein Problem ist, dass Ihr t Instanz nicht richtig initialisiert ist. Sie können dies beheben, indem Sie new anstelle von malloc Ihre Struktur enthält eine string , dessen Konstruktor aufgerufen werden muss. Aufruf von new stellt sicher, dass die t Objekt richtig konstruiert wird.

 t* arglist = new t;

dann den Speicher "freigeben", indem Sie delete :

delete arglist;

Dies weist auf das zweite Problem hin, nämlich dass Ihre t Instanz muss garantiert sein, dass sie während der gesamten Ausführung des Threads aktiv ist. Sie sollten die Zuweisung des Speichers nicht aufheben, bevor der Thread beendet ist. Dies ist ein C++-Beispiel, bei dem die t Objekt garantiert, dass es den Thread überdauert:

#include <thread>

int main()
{
  t arglist = whatever;
  std::thread t(startover, &whatever); // launches thread which runs startover(&arglist)

  // do other stuff

  t.join(); // wait for thread execution to finish

}

Im Allgemeinen sollten Sie statt roher Zeiger auf dynamisch zugewiesene Objekte eine intelligenter Zeiger .

Nebenbei bemerkt, die typedef Syntax für die Deklaration einer struct sieht in C++ ziemlich seltsam aus. Normalerweise würden Sie dies tun:

struct t {
    string fName;
    string str; 
};

3voto

billz Punkte 44208

malloc wird nur Speicher für das Objekt zugewiesen, aber nicht sein Konstruktor aufgerufen

Sie müssen zu neuen

t *arglist = new t;

Geben Sie den Speicherblock arglist nicht frei, bevor der startOver-Thread seinen Inhalt erhält. Sie können ihn innerhalb des Threads oder an anderer Stelle freigeben.

void startOver(void* param)
{
  Param* param_ = (Param*)param;  // get hold of param pointer
  while(true){
    // do something
   }
  delete param_;  // release param when thread finishes
}

void BeginTh()
{
    Param *param = new Param();
    param->fName = "abcd";
    param->str = "yes";
    _beginthread(startOver, 0, (void*)param);
 }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X