-1

I'm trying to spawn some threads on C++ using std::thread but I can't get it to work. If it makes any difference I'm using VS 2015. It fails on thread creation ( t[thread_id] = std::thread(test); ). This is the relevant part of my code:

void test() {}

void threaded_DFT(std::complex<double>* x, std::complex<double>* X, size_t N) {

std::complex<double>* tmp=(std::complex<double>*)malloc(N * sizeof *tmp);
std::thread* t=NULL;
size_t num_threads;

size_t stages = log2(N);
size_t FFT_8_stages = stages / 3;
size_t remainder_stages = stages % 3;

size_t Ns = 1;
for (size_t i=0, Ns = 1; i < FFT_8_stages; i++,Ns=pow(2,3*i))
{
    num_threads = N / 8;
    t = (std::thread*)malloc(num_threads * sizeof *t);
    if (!t)
        exit(EXIT_FAILURE);
    for (size_t thread_id = 0; thread_id < num_threads; thread_id++) {
        t[thread_id] = std::thread(test);   
        //t[thread_id] = std::thread(FFT_8, x, X, N, Ns, thread_id);
    }

    for (size_t thread_id = 0; thread_id < num_threads; thread_id++) {
        t[i].join();
    }

    x = X;
    X = tmp;
    tmp = x;
}
free(t);
...}

And this is the callstack:

ucrtbased.dll!00007ffd296a21c5()    Unknown
ucrtbased.dll!00007ffd296a2363()    Unknown
ucrtbased.dll!00007ffd296c388d()    Unknown
ucrtbased.dll!00007ffd296c28f6()    Unknown
SignalPlot.exe!std::thread::_Move_thread(std::thread & _Other) Line 111 C++
SignalPlot.exe!std::thread::operator=(std::thread && _Other) Line 68    C++
SignalPlot.exe!threaded_DFT(std::complex<double> * x, std::complex<double> * X, unsigned __int64 N) Line 224    C++
SignalPlot.exe!main(int argc, char * * argv) Line 322   C++
SignalPlot.exe!WinMain(HINSTANCE__ * __formal, HINSTANCE__ * __formal, char * __formal, int __formal) Line 113  C++

This should be simple so I'm guessing there is something obvious I'm failing to notice.

Rama
  • 3,222
  • 2
  • 11
  • 26
  • 1
    `t = (std::thread*)malloc(num_threads * sizeof *t);` -- All you've done is allocated the memory -- you have not created any `std::thread` objects. Stop using `malloc`. – PaulMcKenzie Feb 06 '17 at 21:09
  • And don't start using `new`. There is `std::vector`, you know... – LogicStuff Feb 06 '17 at 21:10
  • Another issue: `Ns=pow(2,3*i)` -- Don't use `pow` with integer exponents. There is no guarantee you will get the answer you expect. [See this](http://stackoverflow.com/questions/25678481/why-does-pown-2-return-24-when-n-5-with-my-compiler-and-os) – PaulMcKenzie Feb 06 '17 at 21:22
  • @PaulMcKenzie Thanks for all the advice. Yep I will use bit shifting for the exponentiation. – Mario Betancourt Feb 06 '17 at 22:25

1 Answers1

5

If you use malloc instead of new for any standard library classes, your code simply won't work. malloc doesn't call constructors, and calling them is absolutely required for all Standard Library classes. Why would you ever think of doing such a thing?

  • Thanks ! Haha C guy here getting used to C++. – Mario Betancourt Feb 06 '17 at 21:11
  • 1
    @Mario As other comments have pointed out, you probably don't even need to use new/delete, and in general should not do so. –  Feb 06 '17 at 21:14
  • I've been reading through SO and almost everyone seems to suggest using vectors instead of arrays initialized/destroyed with new/delete. I guess it makes sense from a memory management point of view since it's easier with vectors, but this is not my main concern. Are there differences in performance during heap allocation between the two ways. I'm trying to parallelize the FFT to handle large input signals efficiently. Would vectors over allocate too much memory or have any other unforeseen penalty. – Mario Betancourt Feb 06 '17 at 23:28
  • @Mario If you don't use vectors (or other containers) you simply have to write, and test, a lot more code that does the equivalent to what they do. Your choice. –  Feb 06 '17 at 23:31