当值到指针时,尝试读取或写入受保护的内存

Attempt to read or write protected memory when value to pointer

本文关键字:受保护 内存 读取 指针      更新时间:2023-10-16

我有这个代码:

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.

有人可以帮助我吗?如何解决这个问题?

谢谢。

我建议现代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));

一个问题是您的t实例未正确初始化。你可以通过使用new而不是malloc来解决这个问题 你的结构包含一个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
}
通常,不应使用

原始指针来动态分配的对象,而应使用智能指针。

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

struct t {
    string fName;
    string str; 
};

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