segmentation fault when i access member variables using a callback function

I have a class, in which i declare a static function. I register this function as the callback function for another library. Now, inside this function, i dereference the callback data to the class pointer and invoke a particular non-static member.

The invocation succeeds and the control comes into the non-static member function. But inside this function at the point where i access a member variable of the same class, i get a segmentation fault. This is strange. Can anybody help me with the possible mistake i have made and the solution?

Here is how the code looks like.

class test
{
   int count;
   int callback(const char * a, const char *b)
   {
      print(a);
      print(b);
      count++; //// HERE IS WHERE I GET THE SEGMENTATION FAULT
   }

   public:
   static int callbackwrapper(const char*a, const char *b, void *ptr)
   {
      test *p = (test *)ptr; 
      p->callback(a, b);
   }

   test():count(0) {}
   ~test() {}
   Register()
   {
      registercallback(callbackwrapper);
   }
}

Answers


The ptr passed to callackwrapper is most likely an invalid pointer or not an object of the class test. The invocation still succeeds because as long as you don't access a member variable, a class method is the same as a normal C++ function. Where you access count is when you actually dereference the object, hence the segmentation fault.


Stop using void*s. You will get yourself into a lot of trouble.

Chances are you're calling callback() on an invalid object. I can't tell from the example you gave, but that's what it seems like to me. I would need to see registercallback()'s implementation to be sure, but I note that callbackwrapper() is NOT a static function, and therefore calling it as if it were a static function (which I suspect may be the case) will wreak all sorts of havoc.


int callbackwrapper(const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}

is a member function. That member function is looking for a reference to the object to which it belongs. That is, the function above becomes something like this under the covers:

int callbackwrapper(test* this, const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}

Most likely registercallback is not expecting a member function here.

You can solve this by making callbackwrapper a static member function:

static int callbackwrapper(const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}

Also, don't forget: If you are interfacing with a C library, and that's why you're needing the callback, do keep in mind that functions to be called from C need to be declared extern "C", which would force you to move that function out of the class, and make it

extern "C" int callbackwrapper(const char*a, const char *b, void *ptr)
{
  test *p = (test *)ptr; 
  p->callback(a, b);
}

Need Your Help

Check browser version using Dart rather than JS?

dart angular-dart

Is there an "Angular/Dart" way to detect older unsupported browsers and prevent to continue with an elegant message (there are plenty of examples using javascript) rather than continue and show a w...

Setting Sidekiq :concurrency on Heroku

ruby-on-rails multithreading heroku concurrency sidekiq

I'm having trouble figuring out how exactly concurrency works on Heroku, and how to go about setting the optimal :concurrency value for Sidekiq