尝试在指向值时读取或写入受保护的内存

Edv*_*nka 5 c++ compiler-errors

我有这个代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

在'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.
Run Code Online (Sandbox Code Playgroud)

有人可以帮帮我吗?怎么解决这个问题?

谢谢.

seh*_*ehe 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();
}
Run Code Online (Sandbox Code Playgroud)

请在http://ideone.com/zrXcwH上查看(它不会运行,因为ideone不支持该pthread库).我用MS Visual C++测试了这个.

如果arg_t要复制非常昂贵,您可以简单地将其移动到另一个线程:

auto worker = std::async(startOver, 0, std::move(args));
Run Code Online (Sandbox Code Playgroud)


jua*_*nza 5

一个问题是您的t实例未正确初始化.您可以通过使用new而不是malloc您的struct hold 来修复它,string需要调用其构造函数.调用new可确保t正确构造对象.

 t* arglist = new t;
Run Code Online (Sandbox Code Playgroud)

然后通过调用"释放"内存delete:

delete arglist;
Run Code Online (Sandbox Code Playgroud)

这指出了第二个问题,即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

}
Run Code Online (Sandbox Code Playgroud)

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

顺便说一下,在C++中typedef声明一个struct看起来非常奇怪的语法.通常,你会这样做:

struct t {
    string fName;
    string str; 
};
Run Code Online (Sandbox Code Playgroud)

  • 这将如何解决他的问题?到新线程放在它上面时,该对象仍然会消失. (2认同)