Attempt to use a deleted function - c++

From what I can gather online the cause of this is most likely related to trying to copy a thread (which you can't do). I'm not sure why this problem is arising though. I do suspect which lines it arises in though.
Worker thread definition:
void WorkerThread(SharedLList<uint32_t> *workQueue, std::mutex *dataLock, uint8_t *data, uint32_t *seenStates, int depth)
Code in calling function:
SharedLList<uint32_t> workQueue;
std::mutex lock;
uint8_t *stateDepths = new uint8_t[s.GetMaxRank()];
uint32_t seenStates = 1;
int currDepth = 0;
for (int i = 0; i < numThreads; i++)
{
threads[i] = new std::thread(WorkerThread, std::ref(workQueue), std::ref(lock), stateDepths, std::ref(seenStates), currDepth);
}
Thread
-> Semantic Issue
-> Attempt to use a deleted function
This is the line:
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
How can I fix this issue? What is wrong with my code?

Your thread function is declared as accepting pointers as parameters. Yet you pass references as arguments. This mismatch exists for all pointer parameters except uint8_t *data.

Related

Dereferencing void pointer to assign value to struct

I have several structs containing various combinations of parameters. I wrote a function that takes a void pointer reference to the structs (there are several different types), and writes information from the data parameter into them. Here's the function below:
void SubModelBase::writeDataStruct(byte msgID, void *ptr, QByteArray data)
{
*(byte*)ptr[0] = msgID;
*(byte*)ptr[1] = data.length();
for (int i = 2; i < data.length(); i++)
{
*(byte*)ptr[i] = data.at(i);
}
}
The void *ptr is the reference to the struct that I want to write the data into but I'm having issues deferencing the pointer so I can write into it. I'm sure I'm just missing something silly in my syntax here but I'm not seeing it at the moment...
EDIT:
Ok, I rewrote the function to first cast the void pointer to a byte pointer before assigning values:
void SubModelBase::writeDataStruct(byte msgID, void *ptr, QByteArray data)
{
byte* structData = (byte*)ptr;
structData[0] = msgID;
structData[1] = data.length();
for (int i = 0; i < data.length(); i++)
{
structData[i + 2] = data.at(i);
}
}
Not tested yet but now it at least compiles. I did it this way because there are over 30-40 different structs that need to have data filled in them and I needed a single function that can handle the operation easily without knowing the details of each struct. However, if there is a better way to approach the problem, I'm definitely open to ideas.
EDIT 2: Fixed logic error in loop
What you seem to be looking for is a template so the compiler creates the correct method when you need it.

CPP std::thread attempt to use a deleted function

First of all, I want to say that i already made researches on the subject, but nothing relevant...
(Error creating std::thread on Mac OS X with clang: "attempt to use a deleted function")
(Xcode 7: C++ threads ERROR: Attempting to use a deleted function)
(xcode - "attempt to use a deleted function" - what does that mean?)
And here's my issue...:
clang error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:347:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
And that's my code:
bool GenAI::loadAIs()
{
bool ret = true;
if (_nbThread > 1)
{
std::vector<std::thread> threads;
for (unsigned int i = 0; i < _nbThread; ++i)
threads.push_back(std::thread(static_cast<void (GenAI::*)(bool &, unsigned int)>(&GenAI::loadAIs), this, ret, i));
for (unsigned int i = 0; i < _nbThread; ++i)
threads[i].join();
}
else
loadAIs(ret, 0);
return ret;
}
// And the prototype of the function that i try to call
void GenAI::loadAIs(bool & ret, unsigned int iThread);
If some one could help me that'd be really helpful ! :)
Regards ;)
To pass reference to thread, you have to use std::reference_wrapper, that you can obtain with std::ref. So your code becomes:
threads.emplace_back(static_cast<void (GenAI::*)(bool &, unsigned int)>(&GenAI::loadAIs),
this,
std::ref(ret),
i));
Note:
bool ret should probably be std::atomic<bool> ret, or should should have one bool by thread. Else you may have concurrent access on ret.
The deleted function that it is complaining about is a deleted copy constructor for const thread.
For the deleted function problem, you can use:
threads.emplace_back(
Instead of:
threads.push_back(
What the commenter also referred to is that the function is creating more than one thread and passing to them a reference to the same boolean return variable.
It will crash if you don't use atomic_bool and even if you do, they will all report back to the same memory location, making the function miss the notification if one of them returns false.

Creating an array of objects causes an issue

I create the two following objects:
bool Reception::createNProcess()
{
for (int y = 0; y < 3; ++y)
{
Process *pro = new Process; // forks() at construction
Thread *t = new Thread[5];
this->addProcess(pro); // Adds the new process to a vector
if (pro->getPid() == 0)
{
for (int i = 0; i < 5; ++i)
{
pro->addThread(&t[i]); // Adds the new thread to a vector
t[i].startThread();
}
}
}
Where I create 3 processes (that I have encapsulated in Process) and create 5 threads in each of these processes.
But I'm not sure the following line is correct:
Thread *t = new Thread[5];
Because my two functions addProcess and addThread both take a pointer to Process and Thread respectively and yet the compiler asks for a reference to t[i] for addThread and I don't understand why.
void Process::addThread(Thread *t)
{
this->threads_.push_back(t);
}
void Reception::addProcess(Process *p)
{
this->createdPro.push_back(p);
}
createdPro is defined in the Reception class as follows:
std::vector<Process *> createdPro;
and threads_ in the Process class like such:
std::vector<Thread *> threads_;
And the error message (as obvious as it is) is as follows:
error: no matching function for call to ‘Process::addThread(Thread&)’
pro->addThread(t[i]);
process.hpp:29:10: note: candidate: void Process::addThread(Thread*)
void addThread(Thread *);
process.hpp:29:10: note: no known conversion for argument 1 from ‘Thread’ to ‘Thread*’
Even though I defined my Thread as a pointer.
You have defined the member function to take a pointer:
void Process::addThread(Thread *t)
{
...
}
You then invoke this function for &t[i], which is a pointer and should work perfectly:
pro->addThread(&t[i]); // Adds the new thread to a vector
You could also invoke it with t+i and it would still be ok. However your error message tells us something different: the compiler doesn't find a match for pro->addThread(t[i]); (i.e. the & is missing).
Either you made a typo in your question, or you made a typo in your code. Or you have another invocation somewhere where you've forgotten the ampersand: t[i] would of course designate an object (it's equivalent to *(t+i) ) and not a pointer, and cause the error message you have (demo mcve)

OLE macro in a for loop

According to MSDN documentation for OLE conversion macros, if we use a macro in a for loop for example, it may end up allocating more memory on stack leading to stack overflow.
This is the example provided on MSDN
void BadIterateCode(LPCTSTR* lpszArray)
{
USES_CONVERSION;
for (int ii = 0; ii < 10000; ii++)
pI->SomeMethod(ii, T2COLE(lpszArray[ii]));
}
In the above example T2COLE is used inside a for loop which may lead to stack overflow, to avoid this the method call is encapsulated into a function like this
void CallSomeMethod(int ii, LPCTSTR lpsz)
{
USES_CONVERSION;
pI->SomeMethod(ii, T2COLE(lpsz));
}
void MuchBetterIterateCode2(LPCTSTR* lpszArray)
{
for (int ii = 0; ii < 10000; ii++)
CallSomeMethod(ii, lpszArray[ii]);
}
Can we just send the LPCTSTR to another function instead of encapsulating the whole method like this,
LPCOLESTR CallSomeMethod(LPCTSTR lpsz)
{
USES_CONVERSION;
return T2COLE(lpsz);
}
void BadIterateCode(LPCTSTR* lpszArray)
{
for (int ii = 0; ii < 10000; ii++)
pI->SomeMethod(ii, CallSomeMethod(lpszArray[ii]));
}
Can anyone tell me if it is safe use of OLE macro or still we may run into stack overflow?
Will there be any other issues by using the above method?
The third example will not work because the T2COLE object created in the method will be destroyed as soon as you return from the function. As you note in your question, the object is created on the stack, and the usual stack rules apply in this situation - the object will be destroyed as soon as you go out of scope, and you'll be accessing garbage data in the 3rd case.
The second case is the correct mechanism to use for using the data without triggering a stack overflow as upon return from the function, the memory that was allocated by the T2COLE will be freed.
I'm not aware of how the implementation of T2COLE works, but in C, you could achieve the same behaviour by using the alloca function which suffers from the same issue - as soon as you return from the function, you should consider the pointer and the data that it points at as invalid.

Multithreaded matrix multiplication in C++

I've been having trouble with this parallel matrix multiplication code, I keep getting an error when trying to access a data member in my structure.
This is my main function:
struct arg_struct
{
int* arg1;
int* arg2;
int arg3;
int* arg4;
};
int main()
{
pthread_t allthreads[4];
int A [N*N];
int B [N*N];
int C [N*N];
randomMatrix(A);
randomMatrix(B);
printMatrix(A);
printMatrix(B);
struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct));
args.arg1 = A;
args.arg2 = B;
int x;
for (int i = 0; i < 4; i++)
{
args.arg3 = i;
args.arg4 = C;
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args);
if(x!=0)
exit(1);
}
return 0;
}
and the matrixMultiplication method used from another C file:
void *matrixMultiplication(void* arguments)
{
struct arg_struct* args = (struct arg_struct*) arguments;
int block = args.arg3;
int* A = args.arg1;
int* B = args.arg2;
int* C = args->arg4;
free(args);
int startln = getStartLineFromBlock(block);
int startcol = getStartColumnFromBlock(block);
for (int i = startln; i < startln+(N/2); i++)
{
for (int j = startcol; j < startcol+(N/2); j++)
{
setMatrixValue(C,0,i,j);
for(int k = 0; k < N; k++)
{
C[i*N+j] += (getMatrixValue(A,i,k) * getMatrixValue(B,k,j));
usleep(1);
}
}
}
}
Another error I am getting is when creating the thread: "invalid conversion from ‘void ()(int, int*, int, int*)’ to ‘void* ()(void)’ [-fpermissive]
"
Can anyone please tell me what I'm doing wrong?
First you mix C and C++ very badly, either use plain C or use C++, in C++ you can simply use new and delete.
But the reason of your error is you allocate arg_struct in one place and free it in 4 threads. You should allocate one arg_struct for each thread
Big Boss is right in the sense that he has identified the problem, but to add to/augment the reply he made.
Option 1:
Just create an arg_struct in the loop and set the members, then pass it through:
for(...)
{
struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct));
args->arg1 = A;
args->arg2 = B; //set up args as now...
...
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args);
....
}
keep the free call in the thread, but now you could then use the passed struct directly rather than creating locals in your thread.
Option 2:
It looks like you want to copy the params from the struct internally to the thread anyway so you don't need to dynamically allocate.
Just create an arg_struct and set the members, then pass it through:
arg_struct args;
//set up args as now...
for(...)
{
...
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)&args);
}
Then remove the free call.
However as James pointed out you would need to synchronize in the thread/parent on the structure to make sure that it wasn't changed. That would mean a Mutex or some other mechanism. So probably the move of the allocation to the for loop is easier to begin with.
Part 2:
I'm working on windows (so I can't experiment currently), but pthread_create param 3 is referring to the thread function matrixMultiplication which is defined as void* matrixMultiplication( void* ); - it looks correct to me (signature wise) from the man pages online, void* fn (void* )
I think I'll have to defer to someone else on your second error. Made this post a comunnity wiki entry so answer can be put into this if desired.
It's not clear to me what you are trying to do. You start some threads,
then you return from main (exiting the process) before getting any
results from them.
In this case, I'ld probably not use any dynamic allocation, directly.
(I would use std::vector for the matrices, which would use dynamic
allocation internally.) There's no reason to dynamically allocate the
arg_struct, since it can safely be copied. Of course, you'll have to
wait until each thread has successfully extracted its data before
looping to construct the next thread. This would normally be done using
a conditional: the new thread would unblock the conditional once it has
extracted the arguments from the arg_struct (or even better, you could
use boost::thread, which does this part for you). Alternatively, you
could use an array of arg_struct, but there is absolutely no reason to
allocate them dynamically. (If for some reason you cannot use
std::vector for A, B and C, you will want to allocate these
dynamically, in order to avoid any risk of stack overflow. But
std::vector is a much better solution.)
Finally, of course, you must wait for all of the threads to finish
before leaving main. Otherwise, the threads will continue working on
data that doesn't exist any more. In this case, you should
pthread_join all of the threads before exiting main. Presumably,
too, you want to do something with the results of the multiplication,
but in any case, exiting main before all of the threads have finished
accessing the matrices will cause undefined behavior.