0

I wanted to pass a pointer to the thread function, but it gives back

error: attempt to use a deleted function __invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_In...

Code fragment in main

for (int i = 0; i < threadCount; ++i) {
    ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
    ptrTabThreads->join();
    ++ptrTabThreads;
}

And code for checkMin function

void checkMin(int* tab) {
    int sizeOfTable = 0;

    if (tab == ptrTab[threadCount-1])
        sizeOfTable = partSize + additionalNumbers;
    else
        sizeOfTable = partSize;       

    mt.lock();
    for (int i = 0; i < sizeOfTable; ++i) {
        if (tab[i] < minValue) {
            minValue = tab[i];
        }
    }
    mt.unlock(); 
}

Where ptrTab is an array of pointers:

int* ptrTab[threadCount];

Full code is:

#include <iostream>
#include <thread>
#include <condition_variable>
#include <stdlib.h>
#include <climits>

#define threadCount 10
#define numbersCount 75
std::mutex mt;
int minValue = INT32_MAX;
int partSize, additionalNumbers;
int* ptrTab[threadCount];

void checkMin(int value);
void printTab(int *tab);

int main() {
    int tab[numbersCount];
    srand(time(NULL));

    for (int i = 0; i < numbersCount; ++i) {
        tab[i] = rand() % 1000;
        std::cout << " " << tab[i];
    }

    partSize = numbersCount / threadCount;
    additionalNumbers = numbersCount % threadCount;

    for (int i = 0; i < threadCount-1; ++i) {
        int *newTab = new int[partSize];
        ptrTab[i] = newTab;
    }
    int *newTab = new int[partSize+additionalNumbers];
    ptrTab[threadCount-1] = newTab;

    int copiedElements = 0;
    for (int i = 0; i < threadCount-1; ++i) {
        int *tmpTab = ptrTab[i];
        for (int j = 0; j < partSize; j++) {
            tmpTab[j] = tab[copiedElements];
            copiedElements++;
        }
    }
    int *tmpTab = ptrTab[threadCount-1];
    int elementsLeft = numbersCount-copiedElements;
    for (int i = 0; i < elementsLeft; ++i) {
        tmpTab[i] = tab[copiedElements];
        copiedElements++;
    }

    /*for (int i = 0; i < threadCount; ++i) {
        printTab(ptrTab[i]);
    }*/


    //----------------------

    std::thread tabThreads[threadCount];
    std::thread *ptrTabThreads = tabThreads;

    for (int i = 0; i < threadCount; ++i) {
        ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
        ptrTabThreads->join();
        ++ptrTabThreads;
    }

    std::cout << "\n\n" << minValue << "\n\n";

    //for check
    std::cout << "for check: minimal value is ";
    int min = INT32_MAX;
    for (int i = 0; i < numbersCount; ++i) {
        if (tab[i] < min) {
            min = tab[i];
        }
    }
    std::cout << min << "\n\n";

}

void checkMin(int* tab) {
    int sizeOfTable = 0;

    if (tab == ptrTab[threadCount-1]) 
        sizeOfTable = partSize + additionalNumbers;
    else
        sizeOfTable = partSize;        

    mt.lock();
    for (int i = 0; i < sizeOfTable; ++i) {
        if (tab[i] < minValue) {
            minValue = tab[i];
        }
    }
    mt.unlock();
}

void printTab(int *tab) {
    for (int i = 0; i < 10; ++i) {
        std::cout << tab[i] << " ";
    }
    std::cout << "\n\n";
}

Thank you for all your advices.

9
  • Which line of code has error? Commented Jun 15, 2016 at 19:06
  • Please post complete example and information about your compiler. After adding missing variables to above code it compiled cleanly using g++ 5.3.0 on Cygwin. Commented Jun 15, 2016 at 19:10
  • Thank you for your comments! I am compiling the code on OS X, after check it says "Apple LLVM version 7.0.2 (clang-700.1.81)". I will edit my question with full code in a few seconds. Commented Jun 15, 2016 at 19:18
  • 1
    You call join() right after you created thread in the loop, basically making your app convoluted single threaded one, what is the reason? Commented Jun 15, 2016 at 19:26
  • Your pre-declaration of checkMin has int value as parameter instead of int* . Is that maybe somehow the problem? Commented Jun 15, 2016 at 19:29

1 Answer 1

2

The immediate problem which triggers compilation error is right here:

void checkMin(int value);

This is the prototype of your function, and it is incorrect - it should be

void checkMin(int* value); //<-- not the pointer.

But this is not the only one! Your code makes no sense. Look at this fragment:

std::thread tabThreads[threadCount];
std::thread *ptrTabThreads = tabThreads;

for (int i = 0; i < threadCount; ++i) {
    ptrTabThreads = new std::thread(checkMin, ptrTab[i]);
    ptrTabThreads->join();
    ++ptrTabThreads;
}

What's the purpose of all this jumping with pointers? You also have a leak in your code, since you are modifying the pointer you obtained from new before deleteing it. Why not use following simple code?

std::array<std::thread, threadCount> tabThreads;

for (int i = 0; i < threadCount; ++i) {
    tabThreads[i] = std::thread(checkMin, ptrTab[i]);
    tabThreads[i].join();
}

This still serves no pratical purpose (application remains effectively single-threaded, since you join your thread right after creating it), but at least, the code is correct. To really do some fancy multithreading, you need your loop to look like following:

for (int i = 0; i < threadCount; ++i)
    tabThreads[i] = std::thread(checkMin, ptrTab[i]);

for (std::thread& t : tabThreads) // so-called range-for loop. Nice thing!
    t.join();

This will paralellize stuff!

Sign up to request clarification or add additional context in comments.

4 Comments

@Slava, that's for sure. I will highlught this as well.
@SergeyA Yes you're right - incrementing ptrTabThreads was inappropriate. The solution with std::array looks nicer and cleaner. But one more thing I don't understand - why I need to join threads in separate loop?
@RafałP is your intent to have all the threads running at once or did you want them to run one after the other? join waits for the thread to end, so your implementation just creates a thread, waits for it to end, then creates another, instead of starting them all at once.
@kfsone Of course my intent was to run them all at the same time. Thanks for helping me understand the idea correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.