2

I've managed to make a "Pointer-to-member function array" with this code, and it works fine...

typedef string (MyReportHelper::*reportFunctions)();
MyReportHelper helper;

void internalPointersTest(){
    reportFunctions reportFunArray[] = {
        &MyReportHelper::getVersion,
        &MyReportHelper::getModel,
        &MyReportHelper::getUsername,
    };
    int arrSize = sizeof(reportFunArray)/sizeof(reportFunArray[0]);

    for(int i = 0; i < arrSize; i++){
        string result = (helper.*reportFunArray[i])();
        printf("%s", result);
    }
}

But if I put the array declaration outside my function, like the following code, I get a buffer overrun or access violation in Visual Studio, though the code compiles.

typedef string (MyReportHelper::*reportFunctions)();
MyReportHelper helper;

reportFunctions reportFunArray[] = 
{
    &MyReportHelper::getVersion,
    &MyReportHelper::getModel,
    &MyReportHelper::getUsername,
};

void internalPointersTest(){
    int arrSize = sizeof(reportFunArray)/sizeof(reportFunArray[0]);

    for(int i = 0; i < arrSize; i++)
    {
        //next line will fail
        string result = (helper.*reportFunArray[i])();
        printf("%s", result);
    }
}

Does anyone know how to explain why I need to keep it inside the function scope?

4
  • Is that code inside some class? Or top-level? Where does the variable helper come from? Also, can we see the definitions of getVersion, getModel and getUsername? Commented Mar 1, 2013 at 20:52
  • Yes, it's in a class, but I've been able to reproduce it with top-level functions changing what was seen in here: link. I've edited to add the helper declaration Commented Mar 1, 2013 at 21:05
  • What happens if you replace i < arrSize with i < 3? Commented Mar 1, 2013 at 22:51
  • Do you have the array in a different translation unit? If so, can we see the declaration and the definition? Commented Mar 1, 2013 at 22:58

2 Answers 2

2

You didn't index into the array with i.

Secondly, use std::begin and std::end, they already took care of this shit for you.

Finally, PTMFs are basically worthless. Use std::function.

Edit:

What probably happened is that you cocked up the size calculation and VS only happens to notice when it's static. It's probably equally broken in both versions. That's UB for you.

Edit again: You passed an object of type string to printf? If that's not a typedef for const char*, then hello UB. And if it is... then owch, that's really bad.

Sign up to request clarification or add additional context in comments.

1 Comment

Oops, edited for right index. I'll have a look on std::function, but I still don't get it why it fails outside my function...
0
string result = (helper.*reportFunArray[i])();
printf("%s", result);

I assume string is actually std::string? Are you using namespace std; somewhere?

In that case, printf("%s", result); will most likely crash, because it will interpret god-knows-what as the first character of a C-style string. Does the following work?

string result = (helper.*reportFunArray[i])();
std::cout << result;

1 Comment

i'm using std::string, but that printf is just an example. The problem itself is not on printf, but on (helper.*reportFunArray[i])()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.