jeudi 13 août 2020

Cannot pass shared_ptr argument to function pointer

I have a problem with the code that uses function pointer that takes shared_ptr argument.

Here is a sample code.

header.h

#include <functional>
#include <iostream>
template <class T> class FuncWrapper{
    private:
        void (*original_function)(T a);
    public:
        void setFunction(void *func);
        void execFunction(T a, void *data);
};

template <class T> void FuncWrapper<T>::setFunction(void *func){
    original_function = (void (*)(T))func;
}

template <class T> void FuncWrapper<T>::execFunction(T a, void *data){   
    FuncWrapper<T>* wrapper = (FuncWrapper<T>*)data;
    std::cout << "inside wrapper " << *(a.get()) << std::endl;
    wrapper->original_function(a);
}

main.cpp

#include <iostream>
#include <memory>
#include "header.h"

class ClassA{
    public:
        ClassA(std::shared_ptr<int> a){
            FuncWrapper<std::shared_ptr<int>> *fw;
            fw = new FuncWrapper<std::shared_ptr<int>>;
            fw->setFunction((void*)&ClassA::print_int);
            std::function<void(std::shared_ptr<int>)> g = std::bind(&FuncWrapper<std::shared_ptr<int>>::execFunction, fw, std::placeholders::_1, fw);
            g(a);
            delete fw;
        }
    private:
        void print_int(std::shared_ptr<int> x) {
            std::cout << "printing int" << std::endl;
            std::cout << "given int " << *(x.get()) << std::endl;
        }
};

int main(int argc, char * argv[]){
    std::shared_ptr<int> x = std::make_shared<int>(10);
    std::cout << "inside main " << *(x.get()) << std::endl;
    ClassA *temp;
    temp = new ClassA(x);
    delete temp;
    return 0;
}

Result

inside main 10
inside wrapper 10
printing int
Segmentation fault (core dumped)

I cannot figure out why it causes segmentation fault.

Changing std::shared_ptr<int> to int works just fine.
Therefore I assume that it has to do with owenership of shared_ptr, but I'm not familiar with smart pointers and I'm completely at loss.

I want to know

  • why it does not work
  • how to make it work

Limitations are

  • w/o changing print_int function itself
  • execute function within FuncWrapper<T>::execFunction
  • FuncWrapper<T>::execFunction has to be static

Otherwise, it is free to change. (inside ClassA constructor, inside main execFunction etc.)

Aucun commentaire:

Enregistrer un commentaire