1

I am trying to call function testaddresscall() which is defined like:

void testaddresscall()
{
   printf("success");
}

int main(void)
{
   void(*testaddresscallfunc)(void);
   testaddresscallfunc= &testaddresscall;
   cout << *testaddresscallfunc; //it printed 0x012D2050

   typedef void testfunc(void);
   testfunc* callbyaddress = (testfunc*)0x012D2050;
   callbyaddress();
}

Then this happens

Unhandled exception at 0x012D2050 in test.exe: 0xC0000005: Access violation executing location 0x012D2050.

Nullptr
  • 221
  • 2
  • 5
  • 11
  • I am a beginner in pointers... – Nullptr May 05 '15 at 17:16
  • Though I am wrong about one thing. The dereferencing is optional. See this example I've put up: https://goo.gl/zaecDC the first and third options do the same thing. Which surprises me... – JCx May 05 '15 at 18:11
  • We are talking at cross-purposes, and besides my original comment was inaccurate. I'm going to delete all of mine I think and if you could pretend I never spoke that'd be great ;-) Although it was interesting to discover that *functionptr and functionptr return the same value. – JCx May 05 '15 at 18:19
  • @JCx: Yep, that's because, similar to the way an array reference will (in some circumstances) decay to a pointer to the array's first element, a function reference will (in some circumstances) decay to a pointer to the function itself. So when you dereference the function pointer, you get the function, which decays right back to a function pointer. – Benjamin Lindley May 05 '15 at 18:25

2 Answers2

5

Don't do that. The address of the function will change every time you run the code.

BadZen
  • 4,083
  • 2
  • 25
  • 48
  • If you like, you could safely store the address within a variable, and call using that. But not a fixed, compile-time constant. It won't point to your function at all, or even to anything in your valid memory space... – BadZen May 05 '15 at 17:16
  • Incorrect, if the program is linked with the '/DYNAMICBASE:NO' flag. Which, I just found out. – Nullptr May 05 '15 at 17:32
  • 3
    You're not understanding that option (which exists only in the particular compiler you are using on windows, VC, by the way). DYNAMICBASE:NO builds an object that will not be layout-randomized at runtime. This is a feature that increases security and frustrates virus authors, among other things. It does not guarantee that the layout will be fixed between invocations. And you certainly cannot use the same layout if you change the code in simple ways - such as add/remove functions, variables, etc, etc. – BadZen May 05 '15 at 17:35
3

This code works and I think illustrates the problem:

#include <iostream>

void testaddresscall()
{
 std::cout << "success" << std::endl;
}

int main(void)
{
   void(*testaddresscallfunc)(void);
   testaddresscallfunc= &testaddresscall;

   std::cout << (void*)&testaddresscallfunc << std::endl;
   std::cout << (void*)testaddresscallfunc << std::endl;

   typedef void testfunc(void);
   testfunc* callbyaddress = testaddresscallfunc;
   callbyaddress();
}

Output
0xbfa9c29c
0x80488b0
success

1) I would not do this:

testfunc* callbyaddress = (testfunc*)0x012D2050;

You have no guarantee that the address will be the same for each execution.

2) You have taken the address of the pointer, instead of the value... Notice that std::cout gives different addresses for the two. You are interested in the value of the pointer (as this is a pointer to function)...

Werner Erasmus
  • 3,988
  • 17
  • 31