Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attempt to read or write protected memory when value to pointer

I have this 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);
}

And at 'arglist->fName = "comBomber";' i get this error:

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.

Anyone can help me ? How solve this problem ?

Thanks.

like image 827
Edvinas Pranka Avatar asked Nov 24 '12 11:11

Edvinas Pranka


3 Answers

One problem is that your t instance is not properly initialized. You can fix that by it by using new instead of malloc Your struct holds a string, whose constructor needs to be called. Calling new ensures that the t object gets constructed properly.

 t* arglist = new t;

then "free" the memory by calling delete:

delete arglist;

This points to the second problem, which is that your t instance must be guaranteed to be alive during the whole execution of the thread. You should not de-allocate its memory until the thread is finished. This is a C++ example where the t object is guaranteed to outlive the thread:

#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

}

In general, Instead of using raw pointers to dynamically allocated objects, you should use a smart pointer.

As an aside, the typedef syntax for declaring a struct looks pretty strange in C++. Normally, you would do this:

struct t {
    string fName;
    string str; 
};
like image 33
juanchopanza Avatar answered Oct 19 '22 00:10

juanchopanza


I suggest modern C++ style:

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

See it on http://ideone.com/zrXcwH (it doesn't run because ideone doesn't support the pthread library). I tested this with MS Visual C++.

If arg_t would be very expensive to copy, you can simply move it to the other thread:

auto worker = std::async(startOver, 0, std::move(args));
like image 116
sehe Avatar answered Oct 18 '22 22:10

sehe


malloc will only allocate memory for object but will not call its constructor

you need change to new

t *arglist = new t;

Also, do not release arglist memory block before the startOver thread gets its content. you can release it inside the thread or somewhere else.

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);
 }
like image 39
billz Avatar answered Oct 19 '22 00:10

billz