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

在 '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

一个问题是您的t实例未正确初始化。您可以通过使用new而不是malloc您的结构包含 a来解决此问题,string需要调用其构造函数。调用new可确保t正确构造对象。

 t* arglist = new t;

然后通过调用“释放”内存delete

delete arglist;

这就指向了第二个问题,即t在线程的整个执行过程中必须保证你的实例是存活的。在线程完成之前,您不应取消分配其内存。这是一个 C++ 示例,其中t保证对象的寿命比线程长:

#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

}

通常,您应该使用智能指针,而不是使用原始指针来动态分配对象。

typedef顺便说一句,在 C++中声明 a的语法struct看起来很奇怪。通常,您会这样做:

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 回答