Reputation: 1677
I have a problem with copying the content of a structure.. following situation...I have a struct arg_struct in my class Session:
struct Session::arg_struct
{
const char* targetFilePath;
const char* url;
unsigned int thread_id;
Session::ThreadFinishedCallbackFunction callback;
};
and in one of my method I start a thread and give the struct to the function that will be executed:
{
...
arg_struct args;
args.targetFilePath = targetFilePath;
args.url = req_url;
args.thread_id = ++mThread_id;
args.callback = callback;
curl_global_init(CURL_GLOBAL_ALL);
error = pthread_create(&thread,NULL,download,&args);
}
Now the download function will be executed:
void* download(void* arguments)
{
Session::arg_struct ar = *(Session::arg_struct*) arguments;
Session::arg_struct args;
args.targetFilePath = new char[strlen(ar.targetFilePath)];
args.url = new char[strlen(ar.url)];
strcpy(const_cast<char*>(args.targetFilePath),ar.targetFilePath);
strcpy(const_cast<char*>(args.url),ar.url);
args.callback = ar.callback;
args.thread_id = ar.thread_id;
cout << "copied" << endl;
CURL *curl;
FILE* datafile;
datafile = fopen(args.targetFilePath, "w");
if(datafile != NULL)
{
curl = curl_easy_init();
curl_easy_setopt(curl,CURLOPT_URL,args.url);
curl_easy_setopt(curl,CURLOPT_WRITEDATA,datafile);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
fclose(datafile);
} else {
cout << "error: failed to open file!" << endl;
return NULL;
}
At the beginning of the download function I copy the struct (I quess ;) ) but I got the error that the file can not be opened. The problem is that when I try to open the file with fopen() the struct is empty. It seems that I havent copied the struct correctly or the pointer to the struct (void* arguments) is allready not useable. Have you got any suggestions?
Upvotes: 2
Views: 253
Reputation: 361302
There are two kinds of copy:
Read this:
If you need shallow copy, then this is enough,
arg_struct shallow_copy = original;
No need to copy each element.
However, if you need deep copy, then you have to allocate memory for pointer members of the struct, and then copy the content using strcpy
, not using assignment. Since this is cumbersome approach, better change the types of these variables from char*
to std::string
. Then you can simple write:
arg_struct deep_copy = original;
Now this is deep copy. All it requires you to change the pointers to std::string
.
Upvotes: 3
Reputation: 1798
It looks as though when you create the struct, you're doing it on the stack. When that function returns, its stack goes away, and so does the struct. It seems to me that the struct is going away before download is getting a chance to copy it.
Instead you should allocate the struct on the heap (using new), and deallocate it in download. Also, since download would be taking ownership of it, you wouldn't really have to copy it.
Upvotes: 5