Thanks for the help from @edrezen in finding the solution to my problem. I can't believe it was so simple. An index error. I updated the code slightly to fix this indexing error, the carries array should always be 1 larger than the input array. The updated code for the controller thread is shown below:
void ControllerThread(int &iterationCount, bool &finishedIterations, vector<int> &doneThreads, vector<int> &startIndexes, vector<int> &endIndexes, vector<uint8_t> &output, vector<uint8_t> &carries, bool &isAnyOne, int numThreads, vector<uint8_t> &input) {
iterationCount = 0;
while(iterationCount < totalIterations) {
unique_lock<mutex> lock(mtx);
cv.wait(lock, [&doneThreads] {
// If all threads are done then start
return all_of(doneThreads.begin(), doneThreads.end(), [](int done) {return done >= 1;});
});
// Carry propogation area
while (isAnyOne) {
isAnyOne = false;
for (int i = 0; i < carries.size(); i++) {
uint8_t intermediate;
if (output.size() > i) {
intermediate = output.at(i) + carries.at(i);
carries[i] = 0;
uint8_t localCarry = (intermediate >= 10) ? 1 : 0;
if (localCarry == 1) {
isAnyOne = true;
intermediate -= 10;
if (carries.size() > i)
carries[i+1] = localCarry;
else
carries.push_back(localCarry);
}
output[i] = intermediate;
}
else if (carries[i] > 0) {
intermediate = carries.at(i);
carries[i] = 0;
output.push_back(intermediate);
break;
}
}
}
OutputList(output);
if (iterationCount > 0) {
input = output;
}
while (carries.size() < input.size() + 1) {
carries.push_back(0);
}
// Set conditions for threads
int itemsPerThread = input.size() / numThreads;
// If the input size and number of threads aren't divisible
int lastThreadExcess = input.size() % numThreads;
// Initializing all the threads
for (int i = 0; i < numThreads; i++) {
int startIndex = i * itemsPerThread;
int endIndex = (i+1) * itemsPerThread;
if (i == numThreads - 1) {
endIndex += lastThreadExcess;
}
startIndexes[i] = startIndex;
endIndexes[i] = endIndex;
}
// Resetting the threads to start doing tasks again
for (int j = 0; j < doneThreads.size(); j++) {
doneThreads[j] = 0;
}
// Starting the threads to do their tasks
lock.unlock();
cv.notify_all();
iterationCount++;
}
// This top section of thread processing is finished so setting this variable
finishedIterations = true;
}