5

私はこのコードを持っています:

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);
}

そして at 'arglist->fName = "comBomber";' 私はこのエラーが発生します:

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.

誰でも私を助けることができますか?この問題をどのように解決しますか?

ありがとう。

4

3 に答える 3

6

モダンな C++ スタイルをお勧めします。

#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();
}

http://ideone.com/zrXcwHで参照してください(ideone はライブラリをサポートしていないため、実行されませんpthread)。これを MS Visual C++ でテストしました。

コピーするのに非常にコストがかかる場合arg_tは、単純に他のスレッドに移動できます。

auto worker = std::async(startOver, 0, std::move(args));
于 2012-11-24T12:12:15.333 に答える
5

1 つの問題は、tインスタンスが適切に初期化されていないことです。Your struct hold a のnew代わりに使用することで、それを修正できます。そのコンストラクターを呼び出す必要があります。呼び出しにより、オブジェクトが適切に構築されることが保証されます。mallocstringnewt

 t* arglist = new t;

次に、次を呼び出してメモリを「解放」しますdelete

delete arglist;

これは 2 番目の問題を示していtます。つまり、スレッドの実行中にインスタンスが生きていることが保証されなければならないということです。スレッドが終了するまで、メモリの割り当てを解除しないでください。tこれは、オブジェクトがスレッドよりも長く存続することが保証されている C++ の例です。

#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

}

一般に、動的に割り当てられたオブジェクトへの生のポインターを使用する代わりに、スマート ポインターを使用する必要があります。

余談ですが、typedefa を宣言するための構文はstruct、C++ ではかなり奇妙に見えます。通常、次のようにします。

struct t {
    string fName;
    string str; 
};
于 2012-11-24T11:34:37.630 に答える
3

mallocオブジェクトにメモリを割り当てるだけで、そのコンストラクターは呼び出さない

新しいものに変更する必要があります

t *arglist = new t;

また、startOver スレッドがコンテンツを取得する前に、arglist メモリ ブロックを解放しないでください。スレッド内または他の場所で解放できます。

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);
 }
于 2012-11-24T11:34:18.783 に答える