AlexKite
AlexKite

Reputation: 3

Pointer to array of pointers to functions

The idea is to call different functions based on their index in table. But line 27 generates the runtime error (( I tried to fix but didn't succeed ((( Here's the simplified code:

#include <iostream>

void f1 (void) {
  std::cout << "f1" << "\n";
}

void f2 (void) {
  std::cout << "f2" << "\n";
}

typedef void (*fPtr[3])(void); // simple "[]" instead of "[3]" gets the compile error

class modeChanger {
  public:
    modeChanger (fPtr funcArray);
    void op ();
  private:
    fPtr *_funcArray;
};

modeChanger::modeChanger (fPtr funcArray) {
  _funcArray = (fPtr *) funcArray;
}

void modeChanger::op () {
  (*_funcArray[0])();
  (*_funcArray[1])(); // Line 27: this line generates a runtime error! Just comment it to get all work
}

void (*modeFuncArray[])(void) = {f1, f2, f2};

modeChanger *mode = new modeChanger (modeFuncArray);

int main() {
    (*modeFuncArray[1])(); // Works fine

    mode->op(); // generates a runtime error
    return 0;
}

This works good:

(*_funcArray[0])();

as well as this:

(*modeFuncArray[1])();

but this generates a runtime error...

(*_funcArray[1])(); 

Seems that incrementing of _funcArray is incorrect for some reason.

Upvotes: 0

Views: 73

Answers (3)

Caleth
Caleth

Reputation: 62531

Applying @Someprogrammerdude's advice:

#include <iostream>
#include <array>
#include <functional>

void f1 (void) {
  std::cout << "f1" << "\n";
}

void f2 (void) {
  std::cout << "f2" << "\n";
}

using fPtr = std::function<void()>;
using fPtrs = std::array<fPtr, 3>;

class modeChanger {
  public:
    modeChanger (fPtrs funcArray);
    void op ();
  private:
    fPtrs _funcArray;
};

modeChanger::modeChanger (fPtrs funcArray) : _funcArray(funcArray) { }

void modeChanger::op () {
  _funcArray[0]();
  _funcArray[1]();
}   

int main() {
    fPtrs modeFuncArray = {f1, f2, f2};
    modeChanger mode(modeFuncArray);
    modeFuncArray[1]();

    mode.op(); 
    return 0;
}

And thus instead of "hard to declare" C types, we have things as easy as int, and all is well.

Upvotes: 2

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38342

fPtr *_funcArray; this is the pointer to array, not an array of pointers. You suppressed warnings with help of type casts. See bellow the fixed code.

#include <iostream>

void f1 (void) {
  std::cout << "f1" << "\n";
}

void f2 (void) {
  std::cout << "f2" << "\n";
}

typedef void (*fPtr)(void);

class modeChanger {
  public:
    modeChanger (fPtr *funcArray);
    void op ();
  private:
    fPtr *_funcArray;
};

modeChanger::modeChanger (fPtr *funcArray) {
  _funcArray = funcArray;
}

void modeChanger::op () {
  (*_funcArray[0])();
  (*_funcArray[1])(); // Line 27: this line generates a runtime error! Just comment it to get all work
}

void (*modeFuncArray[])(void) = {f1, f2, f2};

modeChanger *mode = new modeChanger (modeFuncArray);

int main() {
    (*modeFuncArray[1])(); // Works fine

    mode->op(); // generates a runtime error
    return 0;
}

Upvotes: 3

Arkady Godlin
Arkady Godlin

Reputation: 588

as you use c++, you should use c++ features and not C, you should use <functional>

#include <iostream>
#include <functional>
void f1(void) {
    std::cout << "f1" << "\n";
}

void f2(void) {
    std::cout << "f2" << "\n";
}

typedef void(*fPtr[3])(void); // simple "[]" gets the compile error

class modeChanger {
public:
    modeChanger(std::function<void(void)>* funcArray);
    void op();
private:
    std::function<void(void)> * _funcArray;
};

modeChanger::modeChanger(std::function<void(void)>* funcArray) {
    _funcArray = funcArray;
}

void modeChanger::op() {
    _funcArray[0]();
    _funcArray[1](); // this line generates a runtime error! Just comment it to get all work
}

std::function<void(void)>  modeFuncArray[]  = { f1, f2, f2 };

modeChanger *mode = new modeChanger(modeFuncArray);

int main() {
    modeFuncArray[1](); // Works fine

    mode->op(); // generates a runtime error
    return 0;
}

Upvotes: 0

Related Questions