0

I've got a class with a simple thread pointer, that I use to start a function in a new thread from my constructor.

class Tty {
public:
    Tty();
private:
    void foo();
    std::thread tFoo;
};

using namespace std;

Tty::Tty() {
    tFoo = thread(&Tty::foo, this);
}

void Tty::foo()  {
  cout << "test";
}

My main can be resumed to that:

int main(int argc, char** argv) {
    Tty* tty = new Tty();
    while (!exitCheck());
}

But when I run this code, I got this error at runtime: malloc(): memory corruption: 0x000000000133c170. What did I do wrong ?

Antoine C.
  • 3,730
  • 5
  • 32
  • 56
  • Your example does not require the use of any pointers. Also note there's a `std::exit` function that you might be bringing into the global namespace with the using directive (or it might already be there anyway). – chris Aug 08 '14 at 13:07
  • 2
    Funny that you can run this code. It doesn't compile for me. – PlasmaHH Aug 08 '14 at 13:09
  • Then how do I keep the thread w/o a pointer ? – Antoine C. Aug 08 '14 at 13:09
  • @LoveMetal, I'm not sure what you mean by "keep". You can initialize it with the constructor initializer list or a non-static data member initializer. It's "kept" by your object until that dies (which is the end of the scope it's in if `main` would just use a regular object). – chris Aug 08 '14 at 13:10
  • Well, forgot that. But when I use `std::thread tFoo`, and when I initialize it in the constructor `tFoo = thread(&Tty::foo, this);`, I got the same error – Antoine C. Aug 08 '14 at 13:13
  • @PlasmaHH What is the given error ? I got no warnings (g++) – Antoine C. Aug 08 '14 at 13:15
  • Update your new code; and the New error – Harikrishnan R Aug 08 '14 at 13:15
  • @Harikrishnan R, it's updated. As I said, same error as before – Antoine C. Aug 08 '14 at 13:16
  • @LoveMetal: void value not ignored as it ought to be – PlasmaHH Aug 08 '14 at 13:18
  • @PlasmaHH Which line please ? – Antoine C. Aug 08 '14 at 13:19
  • @LoveMetal How you are compiling this program. You are not using any headers !!. Paste the complete program. – Harikrishnan R Aug 08 '14 at 13:19
  • 1
    [Look, mom. no pointers](http://pastebin.com/NSJ6Ayn2). You may find that `join()` interesting too. – WhozCraig Aug 08 '14 at 13:19
  • @Konrad Rudolph, it is an input checking function, because in fact my program is an SDL program, so it checks if the user did Ctrl+Q binding – Antoine C. Aug 08 '14 at 13:20
  • @LoveMetal: the while(!exit()); one – PlasmaHH Aug 08 '14 at 13:20
  • @Harikrishnan R Complete code is 1000 lines long – Antoine C. Aug 08 '14 at 13:20
  • @LoveMetal, That's not initialization, it's assignment. Initialization uses a [constructor initializer list](http://stackoverflow.com/questions/1711990/what-is-this-weird-colon-member-syntax-in-the-constructor). – chris Aug 08 '14 at 13:21
  • @LoveMetal That part is highly relevant to the question, since there’s noting wrong with the code you’ve posted (disregarding unrelated issues, such as the still unnecessary use of pointers, and the redundant initialisation of the thread). – Konrad Rudolph Aug 08 '14 at 13:22
  • Oh sorry you were right, the error was in another class... Should I delete the question then ? – Antoine C. Aug 08 '14 at 13:24
  • Please provide a SSCCE. The code you provide runs as expected for me, but I have to add missing functions. Maybe the problem is inside this functions. BTW: Your code is terrible and you should use initializer lists for your thread and other things. Having a thread and copy the instance is very bad coding! – Klaus Aug 08 '14 at 13:26
  • @Klaus Sorry, I began the Cpp 2 days ago, but thank you for pointing that out. But as I said I solved my problem, that was in another class. So because the question is pointless and misleading, I'll probably delete it soon – Antoine C. Aug 08 '14 at 13:31
  • @Klaus I checked what initializer lists are. But if I don't want the thread to be executed just when I initialize it, how do I do ? Because I'll have many other instructions to run before that the thread begin – Antoine C. Aug 08 '14 at 13:36

1 Answers1

1

I corrected your sample, fixing lack of thread::join. If you don't want to care about thread::join - then you can use detach().

#include <thread>
#include <iostream>
#include <system_error>

struct Tty
{

  Tty();
 ~Tty();

private:

 void foo();

 std::thread    _tFoo;
};

Tty::Tty()
  : _tFoo(&Tty::foo, this)
{
}

Tty::~Tty()
{
  _tFoo.join();
}

void
Tty::foo()
{
  std::cout << "test" << std::endl;
}

int
main()
{
  try
  {
    Tty t;
  }
  catch (const std::system_error& e)
  {
    std::cerr << e.code() << ", " << e.what() << std::endl;
  }
  catch (const std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }
  catch (...)
  {
    std::cerr << "Unknown exception" << std::endl;
  }
}
Tanuki
  • 449
  • 2
  • 8
  • why using `_` before variable name ? Isn't that implementation reserved ? And also, if I don't want the thread to be executed just when I initialize it, how do I do ? Because I'll have many other instructions to run before that the thread begin. Last thing, if I don't need the join, why should I use `detach()` instead of not using it ? – Antoine C. Aug 08 '14 at 13:40
  • Ok. Lets go step by step: 1. Why to use leading _? To escape clash between function name and variable. For ex. consider method void run() and variable bool run. How the compiler should distinguish one from another? void run() and bool _run solving that quite easy. Also a good style is to use short prefixes for statics _s, constants _c e.t.c. 2. Yes, you can initialize that later. Like this: void run() { _tFoo = std::thread(&Tty:foo, this); } – Tanuki Aug 08 '14 at 13:50
  • What is wrong with inlining methods, especially if they are so short? I think var names with leading underscore are bad style. – Klaus Aug 08 '14 at 13:53
  • 3. You should understand, that basically thread is a lightweight process. By default this process is joinable which means that you can gather some execution results and stats after the thread execution. This is cleared after the join call. If you don't need that - detach() the thread. After the detach the thread start to execute without interference to the main thread, so please assure to wait until it finish ones execution. – Tanuki Aug 08 '14 at 13:55
  • @Klaus, just for your distraction have a look at boost sources. You will get a lot of new ideas about good and bad. And basically inlining is good. But in multithread case inline may point to the wrong instance. – Tanuki Aug 08 '14 at 13:56
  • @user3854264 Well, I met a lot of library and OS things that use a leading underscore. I tend to completly avoid function and variables that use the same name. For getters and setters I use `getVarName()` and `setVarName()`. Thank you for these explanations though – Antoine C. Aug 08 '14 at 13:58
  • @LoveMetal Did I answer all your questions :) – Tanuki Aug 08 '14 at 14:01
  • Pretty much yes, ty again! – Antoine C. Aug 08 '14 at 14:02