• Advertisement
Sign in to follow this  

[C++] Pointer to function in a struct - crash [solved]

This topic is 3613 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, Probably me being stupid...couldn't find what was wrong. I have a pointer to a function which I store in a structure. At some point in the program I call the function. This is the code:
struct Item
{
    void (*function)();

    Item() : function(NULL) {}        
};

struct Object
{
    std::vector<Item> items;

    Object() {}
};

std::vector<Object> objects;

void run_function(int o, int i)
{
    // everything works till here
    objects[o].items.function(); // crashes, does not do anything in execute()
}

void execute()
{
    std::cout << "Function is running\n";
}

int main()
{
    // initialise the vector etc etc
    objects[o].items.function = execute;

    run_function(int some_o, int some_i);
}

What am I missing? Thank you, Decrius [Edited by - Decrius on March 31, 2008 4:14:45 PM]

Share this post


Link to post
Share on other sites
Advertisement
Define "it crashes".

Sounds like you're reading past the end of the allocated memory. Are you sure that objects has at least o+1 elements in it, and it's items vector has at least i+1 elements in it?

Share this post


Link to post
Share on other sites
The application returns 3...it just crashes/stops running.

Yes, I guess I'm allocation something I do not control. And I'm sure the O and I are fine, since its in a for loop which will only loop through the objects/items available.

Share this post


Link to post
Share on other sites
What are you trying to pull exactly, and where is o being declared exactly, because i could not see anywhere in the code, except for the fact you are calling it withing main. i would definitely like to know what he value of o is.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
The application returns 3...it just crashes/stops running.

Yes, I guess I'm allocation something I do not control. And I'm sure the O and I are fine, since its in a for loop which will only loop through the objects/items available.
If it returns 3 then it's not crashing. A crash would be it spitting out an access violation or similar.

I suggest using the debugger to step through the code to determine what throws the error. I suggest reading This if you're not familiar with the debugger (Assuming Visual Studio of course, if you're not using it then use the debugger with whatever IDE you have).

Share this post


Link to post
Share on other sites
I use CodeBlocks ;) (ofcourse hehe)

It says, Segmentation Fault, call stack says this:

Nr Address Function
#0 00000000 ??() (??:??)

Does that mean its a NULL pointer?

Share this post


Link to post
Share on other sites
Apparently it is.

I fixed the problem, though I want to add security for this.

How can I check if its a NULL pointer?

if (objects[o].items.function())
{
objects[o].items.function();
}

Doesn't seem to work =/

Thanks anyways :)

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
It's possible. Is there a reason why you won't post your real code?


Yes, its long and irrelevant. I thought the code I posted was wrong...

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
Apparently it is.

I fixed the problem, though I want to add security for this.

How can I check if its a NULL pointer?

if (objects[o].items.function())
{
objects[o].items.function();
}

Doesn't seem to work =/

Thanks anyways :)
That checks if the return value of function() is 0 (NULL is almost always 0). You probably want: if (objects[o].items.function) (Note the lack of brackets).

Share this post


Link to post
Share on other sites
If you know the code is irrelevant, you know what the problem is, since you can correctly remove irrelevant code. However, you don't know what the problem is, so you don't know what code is irrelevant.

Case in point: the problem was nowhere in the code you posted. Since you made us assume that o and i existed and were sane, there's no reason we should assume that the other parts of the code were wrong (e.g., that you initialized the function pointer). Once you bring assumptions into the mix, it's hard to get the crux of the problem efficiently.

Additionally, for example, if you are walking a pointer out of bounds, reading corrupt memory, or accessing a null pointer, the cause of that bug is almost never near the manifestation site. And all you've appeared to post in the manifestation site.

In the future, post your code without trying to guess at what is and is not relevant.

Share this post


Link to post
Share on other sites
Quote:
Original post by jpetrie
If you know the code is irrelevant, you know what the problem is, since you can correctly remove irrelevant code. However, you don't know what the problem is, so you don't know what code is irrelevant.

Case in point: the problem was nowhere in the code you posted. Since you made us assume that o and i existed and were sane, there's no reason we should assume that the other parts of the code were wrong (e.g., that you initialized the function pointer). Once you bring assumptions into the mix, it's hard to get the crux of the problem efficiently.

Additionally, for example, if you are walking a pointer out of bounds, reading corrupt memory, or accessing a null pointer, the cause of that bug is almost never near the manifestation site. And all you've appeared to post in the manifestation site.

In the future, post your code without trying to guess at what is and is not relevant.


Ok, sorry, will do.

@steve
Ah yes...looks very logic. Thanks.

Share this post


Link to post
Share on other sites
One other question. How can I point to a member function?

class Gui;

class Graphics
{
public:
void button();
};

void Graphics::button()
{
game = true;
restatus();
}

class Gui
{
struct Item
{
Rect rect;
bool active, over, click;

int rotate;

bool fit;
Texture texture, texture_over, texture_click;
void (Graphics::*function)();

Item() : rect(), active(false), over(false), click(false), rotate(0), fit(false), texture(), texture_over(), texture_click(), function(NULL) {}
};

struct Object
{
Rect rect;
bool active;
bool top;
std::vector<Item> items;

Object() : rect(), active(false), top(false) {}
};

public:
void load_prewindow(Graphics *, int, int, int, int, int);

private:
std::vector<Object> objects;
};

void Gui::load_prewindow(Graphics *graphics, int type, int x, int y, int w, int h)
{
objects[0].items[0].function = graphics->*button;
}


This tutorial didn't really work for me: http://www.newty.de/fpt/fpt.html

Share this post


Link to post
Share on other sites
boost::function will allow you to create member function pointers.

In particular, boost::function and boost::bind:


#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>


class Test
{
public:
void print()
{
std::cout << "Worked!" << std::endl;
}
};

int main()
{
//instance of our class
Test test;
boost::function< void () > testFunction = boost::bind(&Test::print, &test);
testFunction();
}

Share this post


Link to post
Share on other sites
Tried that, getting this:

E:/Packs/Boost/include/boost/bind/mem_fn_template.hpp:40: error: cannot apply member pointer `((const boost::_mfi::mf0<void, Graphics>*)this)->boost::_mfi::mf0<void, Graphics>::f_' to `*boost::get_pointer [with T = Graphics*](u)', which is of non-aggregate type `Graphics*'
E:/Packs/Boost/include/boost/bind/mem_fn_template.hpp:40: error: return-statement with a value, in function returning 'void'


class Graphics
{
Graphics();
void button_game();
};

Graphics::Graphics()
{
gui->load_prewindow(this);
}

void Graphics::button_game()
{
game = true;
restatus();
}

class Gui
{
struct Item
{
boost::function< void () > function;
};

struct Object
{
std::vector<Item> items;
};

std::vector<Object> objects;
public:
int load_prewindow(Graphics *);
};

int Gui::load_prewindow(Graphics *graphics)
{
objects[object].items[size].function = boost::bind(&Graphics::button_game, &graphics);
}

Share this post


Link to post
Share on other sites
Nevermind, fixed.

I, ofcourse, had to remove the ampersand ;)

Thanks for your help, first time I use Boost ^^,

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement