I'm trying to 'touch' an object layout that has a pointer to vTable. I'm getting a virtual function pointer by 2 options:
by traversing pointers from object pointer to virtual table pointer and then to the first function in this table.
simply by taking an address using & operator.
In both cases when I call a function through these pointers I get expected calling results. So in the output I see
Derived func
Derived func
But these function pointers are not equal and I don't know why. So for example
funcDerived = 0x00901ac3
derivedFuncPtr = 0x00901ab9
Does anybody have a thought why they are not equal? I use VS 2017 compiler.
class Base
{
public:
virtual void func()
{
std::cout << "Base func" << std::endl;
}
};
class Derived :public Base
{
public:
virtual void func() override
{
std::cout << "Derived func" << std::endl;
}
};
int main()
{
Derived obj;
auto funcDerived = &Derived::func;
unsigned int* objPtr = reinterpret_cast<unsigned int*>(&obj);
auto derivedVTablePtr = reinterpret_cast<unsigned int*>(*objPtr);
auto derivedFuncPtr = reinterpret_cast<void(*)(Derived*)>(*derivedVTablePtr);
derivedFuncPtr(&obj);
(obj.*funcDerived)();
return 0;
}
Related
I would like to assign a name to a thread, the thread itself must do this. The thread is a class member of the class foo.
I would like to start this thread with a lambda but unfortunately I get the error message:
no match for call to '(std::thread) (foo::start()::<lambda()>)
Can someone explain to me where the problem is?
Previously I had created a temporary thread object, and put this with move on the thread "manage", however, I can then give no name.
class foo {
public:
int start()
{
this->manage([this](){
auto nto_errno = pthread_setname_np(manage.native_handle(),"manage"); // Give thread an human readable name (non portable!)
while(1){
printf("do work");
}
});
return 1;
}
private:
int retVal;
std::thread manage;
};
You passed the lambda in a wrong way, after initialization the manage thread can't be initialized again. you should create a new std::thread and assign it.
the following compiles and indeed prints "manage".
class foo {
public:
int start()
{
manage = std::thread([this]{
auto nto_errno = pthread_setname_np(manage.native_handle(),"manage");
char name[16];
pthread_getname_np(pthread_self(), &name[0], sizeof(name));
cout << name << endl;
});
manage.join();
return 1;
}
private:
int retVal;
std::thread manage;
};
Well I have an issue with passing data into a thread using std::thread. I thought I understood the general semantics of copy constructors, etc. but it seems I don't quite grasp the problem. I have a simple class called Log that has hidden it's copy constructor thusly:
class Log
{
public:
Log(const char filename[], const bool outputToConsole = false);
virtual ~Log(void);
//modify behavior
void appendStream(std::ostream *);
//commit a new message
void commitStatus(const std::string str);
private:
//members
std::ofstream fileStream;
std::list<std::ostream *> listOfStreams;
//disable copy constructor and assignment operator
Log(const Log &);
Log & operator=(const Log &);
}
now I have a main based heavily on http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/echo/blocking_tcp_echo_server.cpp
int main()
{
static int portNumber = 10000;
Log logger("ServerLog.txt", true);
logger.commitStatus("Log Test String");
try {
boost::asio::io_service ioService;
server(ioService, portNumber, logger);
}
catch (std::exception &e)
{
std::cerr << "Exception " << e.what() << std::endl;
logger.commitStatus(e.what());
}
return 0;
}
You can see that main calls the function server and passes the IOService, portNumber and logger. The logger is passed by reference, thusly:
using boost::asio::ip::tcp;
void server(boost::asio::io_service &ioService, unsigned int port, Log &logger)
{
logger.commitStatus("Server Start");
tcp::acceptor acc(ioService, tcp::endpoint(tcp::v4(), port));
while(true)
{
tcp::socket sock(ioService);
acc.accept(sock);
std::thread newThread(session, &sock, logger);
newThread.detach();
}
logger.commitStatus("Server closed");
}
I get a compiler error when I try to pass the logger (or the socket) to the thread by reference, but I do not get the error when passing it to the session() by reference
static void session(tcp::socket *sock, Log &logger)
{
std::cout << " session () " << std::endl;
}
Now I thought that I understood correctly that a reference is the same as passing a pointer. That is, it does not call the copy constructor, it simply passes the pointer, which it lets you syntactically treat like it's not a pointer.
error C2248: 'Log::Log' : cannot access private member declared in class 'Log'
1> \log.h(55) : see declaration of 'Log::Log'
1> \log.h(28) : see declaration of 'Log'
...
: see reference to function template instantiation 'std::thread::thread(_Fn,_V0_t &&,_V1_t)' being compiled
1> with
1> [
1> Fn=void (_cdecl *)(boost::asio::ip::tcp::socket *,Log &),
1> _V0_t=boost::asio::ip::tcp::socket *,
1> _V1_t=Log &
1> ]
However if I modify it to pass a pointer, everything is happy
...
std::thread newThread(session, &sock, &logger);
...
static void session(tcp::socket *sock, Log *logger)
{
std::cout << " session () " << std::endl;
}
Why is passing by reference calling my copy constructor. Is there something special happening here because of std::thread? Did I misunderstand the copy constructor and pass by reference?
I get a different but equally baffling error if I try to use std::move() as it is done in the example. Is it possible my VS2012 is not implementing C++11 correctly?
std::thread takes its arguments by value. You can get reference semantics back by using std::reference_wrapper:
std::thread newThread(session, &sock, std::ref(logger));
Obviously you must make sure that logger outlives the thread.
I get a compiler error when I try to pass the logger (or the socket) to the thread by reference
It is not sufficient for the thread's entrypoint function to take a reference type: the thread object itself takes its arguments by value. This is because you usually want a copy of objects in a separate thread.
To get around this, you may pass std::ref(logger), which is a reference wrapper hiding reference semantics under a copyable object.
I am trying to construct a std::thread with a member function that takes no arguments and returns void. I can't figure out any syntax that works - the compiler complains no matter what. What is the correct way to implement spawn() so that it returns a std::thread that executes test()?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
#include <thread>
#include <iostream>
class bar {
public:
void foo() {
std::cout << "hello from member function" << std::endl;
}
};
int main()
{
std::thread t(&bar::foo, bar());
t.join();
}
EDIT:
Accounting your edit, you have to do it like this:
std::thread spawn() {
return std::thread(&blub::test, this);
}
UPDATE: I want to explain some more points, some of them have also been discussed in the comments.
The syntax described above is defined in terms of the INVOKE definition (ยง20.8.2.1):
Define INVOKE (f, t1, t2, ..., tN) as follows:
(t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of
type T or a reference to an object of a type derived from T;
((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous
item;
t1.*f when N == 1 and f is a pointer to member data of a class T and t 1 is an object of type T or a
reference to an object of type T or a reference to an object of a
type derived from T;
(*t1).*f when N == 1 and f is a pointer to member data of a class T and t 1 is not one of the types described in the previous item;
f(t1, t2, ..., tN) in all other cases.
Another general fact which I want to point out is that by default the thread constructor will copy all arguments passed to it. The reason for this is that the arguments may need to outlive the calling thread, copying the arguments guarantees that. Instead, if you want to really pass a reference, you can use a std::reference_wrapper created by std::ref.
std::thread (foo, std::ref(arg1));
By doing this, you are promising that you will take care of guaranteeing that the arguments will still exist when the thread operates on them.
Note that all the things mentioned above can also be applied to std::async and std::bind.
Since you are using C++11, lambda-expression is a nice&clean solution.
class blub {
void test() {}
public:
std::thread spawn() {
return std::thread( [this] { this->test(); } );
}
};
since this-> can be omitted, it could be shorten to:
std::thread( [this] { test(); } )
or just (deprecated)
std::thread( [=] { test(); } )
Here is a complete example
#include <thread>
#include <iostream>
class Wrapper {
public:
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
std::thread member1Thread() {
return std::thread([=] { member1(); });
}
std::thread member2Thread(const char *arg1, unsigned arg2) {
return std::thread([=] { member2(arg1, arg2); });
}
};
int main(int argc, char **argv) {
Wrapper *w = new Wrapper();
std::thread tw1 = w->member1Thread();
std::thread tw2 = w->member2Thread("hello", 100);
tw1.join();
tw2.join();
return 0;
}
Compiling with g++ produces the following result
g++ -Wall -std=c++11 hello.cc -o hello -pthread
i am member1
i am member2 and my first arg is (hello) and second arg is (100)
#hop5 and #RnMss suggested to use C++11 lambdas, but if you deal with pointers, you can use them directly:
#include <thread>
#include <iostream>
class CFoo {
public:
int m_i = 0;
void bar() {
++m_i;
}
};
int main() {
CFoo foo;
std::thread t1(&CFoo::bar, &foo);
t1.join();
std::thread t2(&CFoo::bar, &foo);
t2.join();
std::cout << foo.m_i << std::endl;
return 0;
}
outputs
2
Rewritten sample from this answer would be then:
#include <thread>
#include <iostream>
class Wrapper {
public:
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
std::thread member1Thread() {
return std::thread(&Wrapper::member1, this);
}
std::thread member2Thread(const char *arg1, unsigned arg2) {
return std::thread(&Wrapper::member2, this, arg1, arg2);
}
};
int main() {
Wrapper *w = new Wrapper();
std::thread tw1 = w->member1Thread();
tw1.join();
std::thread tw2 = w->member2Thread("hello", 100);
tw2.join();
return 0;
}
Some users have already given their answer and explained it very well.
I would like to add few more things related to thread.
How to work with functor and thread.
Please refer to below example.
The thread will make its own copy of the object while passing the object.
#include<thread>
#include<Windows.h>
#include<iostream>
using namespace std;
class CB
{
public:
CB()
{
cout << "this=" << this << endl;
}
void operator()();
};
void CB::operator()()
{
cout << "this=" << this << endl;
for (int i = 0; i < 5; i++)
{
cout << "CB()=" << i << endl;
Sleep(1000);
}
}
void main()
{
CB obj; // please note the address of obj.
thread t(obj); // here obj will be passed by value
//i.e. thread will make it own local copy of it.
// we can confirm it by matching the address of
//object printed in the constructor
// and address of the obj printed in the function
t.join();
}
Another way of achieving the same thing is like:
void main()
{
thread t((CB()));
t.join();
}
But if you want to pass the object by reference then use the below syntax:
void main()
{
CB obj;
//thread t(obj);
thread t(std::ref(obj));
t.join();
}
A class t_analyser contains a function which performs some operations on a t_data object and outputs the results.
I would like to add to t_analyser a filter capability: a small and fast function
bool filter(const t_data & d) {...}
which allows to skip the analysis (and the output) if some conditions are met for that particular data. The filter should be setted up easily from the main, so I was thinking to store a shared function pointer in t_analyser and use a lambda to initialize it.
Is this a good approach? My concerns are related to the fact that many analysers can call the same filter function simultaneously in different threads, could this be a problem? Can I simply copy the pointer in the t_analyser's copy constructor? Any hint would be much appreciated.
This could be a problem if your filter function had side effects. Its signature is simple and says that it just makes some decision reading data from t_data, so make sure that t_data is not modified in parallel thread and you'll be fine.
Consider the following program:
#include <iostream>
struct X
{
void foo1(){ std::cout << "foo1" << std::endl; }
void foo2(){ std::cout << "foo2" << std::endl; }
};
typedef void (X::*MemberFunctionPointer)();
struct ByRef
{
ByRef( MemberFunctionPointer& f )
: f_( f )
{
}
void operator()()
{
X x;
(x.*f_)();
}
MemberFunctionPointer& f_;
};
struct ByValue
{
ByValue( MemberFunctionPointer f )
: f_( f )
{
}
void operator()()
{
X x;
(x.*f_)();
}
MemberFunctionPointer f_;
};
int main()
{
MemberFunctionPointer p = &X::foo1;
ByRef byRef( p );
ByValue byValue( p );
byRef();
byValue();
p = &X::foo2;
byRef();
byValue();
return 0;
}
Output:
foo1
foo1
foo2
foo1
Press <RETURN> to close this window...
From this you will notice that in the one case the member function pointer is passed by value (and not shared), and in the other it is passed by reference (and shared). When using the syntax:
foo( void( X::*f)() )...
the pointer to member function is passed by value, and is copied (and cannot be modified) again.
You can declare the function pointer as static + thread specific:
static _declspec(thread) FUNC_TYPE filterFunc;
Each thread that modifies filterFunc works on a different copy of the pointer.
How do I implement a display function for a binary search tree of strings if display is passed as a function pointer to function inorder?
typedef void (*FunctionType)(TreeItemType& anItem);
void display(TreeItemType& anItem);
void BinarySearchTree::inorder(TreeNode *treePtr,
FunctionType visit)
{ if (treePtr != NULL)
{ inorder(treePtr->leftChildPtr, visit);
visit(treePtr->item);
inorder(treePtr->rightChildPtr, visit);
} // end if
} // end inorder
I've tried to write something like:
cout << anItem;
in the body of display but it doesn't work. TreeItemType is a string so do I need to overload the << operator or = operator to convert from TreeItemType to string? I have researched function pointers and can't figure out how to use:
visit(treePtr->item);
to display the tree's item (which is a string).
int main()
{
BinarySearchTree tree;
TreeItemType item = "20";
tree.searchTreeInsert(item);
tree.inorderTraverse(display); // call to inorderTraverse calls inorder
return 0; // indicates successful completion
} // end function main
void display(TreeItemType& anItem)
{
cout << anItem;
}
Definition of TreeItemType:
typedef string TreeItemType;