C++ Array Of Function Pointers problem
-
CNewbie wrote: the assertion happens on this line: (INSFunction.call_ins_function[insptr])(); Ok, what assertion is being fired?
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
Unhandled exception at 0xcccccccc in flowlog.exe: 0xC0000005: Access violation reading location 0xcccccccc. And as you might have guessed, in the debug at that spot, when I look at what is in the array there is nothing but 0xcccccccc where the function addresses should be. When I run the program without debug I get the assertion error on line 1002 of wincore.cpp which is: ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
-
Unhandled exception at 0xcccccccc in flowlog.exe: 0xC0000005: Access violation reading location 0xcccccccc. And as you might have guessed, in the debug at that spot, when I look at what is in the array there is nothing but 0xcccccccc where the function addresses should be. When I run the program without debug I get the assertion error on line 1002 of wincore.cpp which is: ASSERT(pMap->LookupPermanent(hWndOrig) == NULL);
CNewbie wrote: Unhandled exception at 0xcccccccc... This is the standard value for uninitialized local variables in debug mode. One thing to try is the Debug -> Exceptions options to select breaking (rather than stopping) on the raising of an exception. Then you can catch them directly when they happen. See here for more. CNewbie wrote: When I run the program without debug I get the assertion error on line 1002 of wincore.cpp which is: This indicates that you are using something other than VC++ v6. Correct?
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
CNewbie wrote: Unhandled exception at 0xcccccccc... This is the standard value for uninitialized local variables in debug mode. One thing to try is the Debug -> Exceptions options to select breaking (rather than stopping) on the raising of an exception. Then you can catch them directly when they happen. See here for more. CNewbie wrote: When I run the program without debug I get the assertion error on line 1002 of wincore.cpp which is: This indicates that you are using something other than VC++ v6. Correct?
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
I am trying to make an array of function pointers in C++. I have done it sucessfully in C, but I am having a problem with the arrays not giving defined correctly. Syntactically they are correct (or at least according to the compiler they are), but when it comes time to call the function, the arrays show that they are not defined with the functions that i am putting in the arrays. Here is the declaration for both of my function pointer arrays that are public members of my "CDialog" class in my dialog.h file: void (*functionarray1[48])(); void (*functionarray2[160])(); That file also houses the declarations for all of the functions I will use with the arrays. Next I define the 2 arrays in my dialog.cpp file: void (CDialog::*functionarray1[48])() = {CDialog::function1,CDialog::function2}; void (CDialog::*functionarray2[160])() = {CDialog::function3,CDialog::function4}; So according to this function1 should be in functionarray1[0]. function2 in functionarray1[1], etc... but at runtime when i run a debug the array never gets filled and I get an assertion error Here is the code to call the function pointer based on an unknown offset value between 00h and 9Fh in "insptr": CDialog FuncPtr; UINT insptr = (INSNum / 2); (FuncPtr.functionarray1[insptr])(); <----------------- The assertion error happens when the line pointed to executes. I took this syntax from a paper on C++ array of function pointers if anyone can help, I'd really appreciate it.
Your functions are public members. Are you initializing them in the .cpp file at the global scope or in a member function? If global, then I think that you are defining a new array that happens to have the same name as your member variable. You are not assigning values to your member array. Then when you call the function, the array is not initialized. Try this: In your OnInitDialog(): // Init the functions pointers here functionarray1[0] = CDialog::Func1 ; functionarray1[1] = CDialog::Func2 ; Later: // call the functions functionarray1[0]() ; functionarray1[1]() ; Make sure you declare Func1 and Func2 as static in CDialog.h void (*functionarray1[48])(); void static Func1() ; void static Func2() ; Coadtoad
-
yes, I am using VS.NET 2003 or VC++ 7.1 whichever way you want to look at it. My problem would seem to come down to the fact that I am not defining the array correctly, but I dont see why. Maybe you could see what I am doing wrong.
CNewbie wrote: Maybe you could see what I am doing wrong. Try these articles:* http://www.everything2.com/index.pl?node\_id=1509071
-
http://oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/FPT/em\_fpt.html
-
http://mail.nl.linux.org/kernelnewbies/2003-05/msg00447.html
-
http://lists.trolltech.com/qt-interest/2004-07/thread00496-0.html
-
http://publications.gbdirect.co.uk/c\_book/chapter5/function\_pointers.html
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
-
Your functions are public members. Are you initializing them in the .cpp file at the global scope or in a member function? If global, then I think that you are defining a new array that happens to have the same name as your member variable. You are not assigning values to your member array. Then when you call the function, the array is not initialized. Try this: In your OnInitDialog(): // Init the functions pointers here functionarray1[0] = CDialog::Func1 ; functionarray1[1] = CDialog::Func2 ; Later: // call the functions functionarray1[0]() ; functionarray1[1]() ; Make sure you declare Func1 and Func2 as static in CDialog.h void (*functionarray1[48])(); void static Func1() ; void static Func2() ; Coadtoad
yes coadtoad, that is exactly what I am doing. I am initializing them at the global level in the .cpp file as such: void (TMyClass::*funcArr2[48])() = {CDialog::func1,CDialog::func2}; I did it this way because I already know what functions I want in there, this is the way I did it in C and because it is less code to wirte then If i do it within a member function like initdialog. Also is it a rule that the member functions have to be static?
-
yes coadtoad, that is exactly what I am doing. I am initializing them at the global level in the .cpp file as such: void (TMyClass::*funcArr2[48])() = {CDialog::func1,CDialog::func2}; I did it this way because I already know what functions I want in there, this is the way I did it in C and because it is less code to wirte then If i do it within a member function like initdialog. Also is it a rule that the member functions have to be static?
If you want to have function pointers, I believe that the functions must be static, then you can't see the member variables from the static function. You may need to use a different approach like calling a CDialog member function that uses a switch statement to call the member functions. A little bit more messy, but you will have better encapsulation than writing a series of static functions. Coadtoad
-
CNewbie wrote: Maybe you could see what I am doing wrong. Try these articles:* http://www.everything2.com/index.pl?node\_id=1509071
-
http://oopweb.com/CPP/Documents/FunctionPointers/Volume/CCPP/FPT/em\_fpt.html
-
http://mail.nl.linux.org/kernelnewbies/2003-05/msg00447.html
-
http://lists.trolltech.com/qt-interest/2004-07/thread00496-0.html
-
http://publications.gbdirect.co.uk/c\_book/chapter5/function\_pointers.html
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
Hey David. i just wanted to update you on my Function Pointer array problem. I have solved the problem of the arrays not being initialized by filling them within a member thread using an instance of my class as such: CDialog Function; Function.call_function[0] = &CDialog::dFunction1; Function.call_function[1] = &CDialog::dFunction2; However, these are only Local definitions and would need to be redefined whenver this function is called. So what I would rather do is define them globally, but I have not been able to figure out how to do it without error. According to books I read. To declare instances (objects) of a class, you do so by including them at the end of the class declaration outside of the ending curly bracket. I did this using the "extern" keyword so the object could be used throughout all of my source files as such:
class CDialog { public: CDialog(CWnd* pParent = NULL); // standard constructor protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support protected: // Generated message map functions virtual BOOL OnInitDialog(); DECLARE_MESSAGE_MAP() public: CEdit m_sigstrEdit; }extern Function;
I then defined the instance globally in one of my source files as such: CDialog Function; and it compiled without syntax error, but as soon as the program starts I get an assertion error in Line 26 of afxwin1.inl. If I do not use the "extern" keyword i get linker errors about the object already being defined. So I am at a loss about how to implement this globally. I really appreciate your help thus far. -
-
Hey David. i just wanted to update you on my Function Pointer array problem. I have solved the problem of the arrays not being initialized by filling them within a member thread using an instance of my class as such: CDialog Function; Function.call_function[0] = &CDialog::dFunction1; Function.call_function[1] = &CDialog::dFunction2; However, these are only Local definitions and would need to be redefined whenver this function is called. So what I would rather do is define them globally, but I have not been able to figure out how to do it without error. According to books I read. To declare instances (objects) of a class, you do so by including them at the end of the class declaration outside of the ending curly bracket. I did this using the "extern" keyword so the object could be used throughout all of my source files as such:
class CDialog { public: CDialog(CWnd* pParent = NULL); // standard constructor protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support protected: // Generated message map functions virtual BOOL OnInitDialog(); DECLARE_MESSAGE_MAP() public: CEdit m_sigstrEdit; }extern Function;
I then defined the instance globally in one of my source files as such: CDialog Function; and it compiled without syntax error, but as soon as the program starts I get an assertion error in Line 26 of afxwin1.inl. If I do not use the "extern" keyword i get linker errors about the object already being defined. So I am at a loss about how to implement this globally. I really appreciate your help thus far.CNewbie wrote: CDialog Function; Function.call_function[0] = &CDialog::dFunction1; Function.call_function[1] = &CDialog::dFunction2; If
call_function
is an array of function pointers, why not initialize it in the dialog'sOnInitDialog()
method? The other odd-looking thing is thatdFunction1
anddFunction1
do not belong toCDialog
. CNewbie wrote: To declare instances (objects) of a class, you do so by including them at the end of the class declaration outside of the ending curly bracket. You can instantiate an object anytime after the class has been declared. Doing so in the class' header file is odd. CNewbie wrote: }extern Function; I'm surprised this compiled. In any case, I don't think it's necessary. But without a better understanding of what exactly it is you are after, my suggestions are sparse.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
CNewbie wrote: CDialog Function; Function.call_function[0] = &CDialog::dFunction1; Function.call_function[1] = &CDialog::dFunction2; If
call_function
is an array of function pointers, why not initialize it in the dialog'sOnInitDialog()
method? The other odd-looking thing is thatdFunction1
anddFunction1
do not belong toCDialog
. CNewbie wrote: To declare instances (objects) of a class, you do so by including them at the end of the class declaration outside of the ending curly bracket. You can instantiate an object anytime after the class has been declared. Doing so in the class' header file is odd. CNewbie wrote: }extern Function; I'm surprised this compiled. In any case, I don't think it's necessary. But without a better understanding of what exactly it is you are after, my suggestions are sparse.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
What I want to do is define the 2 function pointer arrays with the appropriate functions globally so that I can use them throughout the problem without having to redefine them each time I have to use them. The 2 function pointer arrays are as follows: void (*call_cmd_function[160])(); void (*call_ins_function[48])(); The functions (NOTE: I did declare them in my class, just didnt put them in the class example above) for both of these arrays are named "dFunction 1 through 45" and "dFunction 46 through 99". My Class is CDialog. If you need anymore info Please ask, I really appreciate the help.
-
What I want to do is define the 2 function pointer arrays with the appropriate functions globally so that I can use them throughout the problem without having to redefine them each time I have to use them. The 2 function pointer arrays are as follows: void (*call_cmd_function[160])(); void (*call_ins_function[48])(); The functions (NOTE: I did declare them in my class, just didnt put them in the class example above) for both of these arrays are named "dFunction 1 through 45" and "dFunction 46 through 99". My Class is CDialog. If you need anymore info Please ask, I really appreciate the help.
CNewbie wrote: What I want to do is define the 2 function pointer arrays with the appropriate functions globally so that I can use them throughout the problem without having to redefine them each time I have to use them. Right. The compiler is never happy when it encounters a redefinition. You can certainly make the arrays global to the entire program. However, they must be initialized within some function (e.g.,
main()
). After that, they can be used from wherever they are needed. And, as you have already discovered, if the arrays are needed in more than one file, you'll need to employ theextern
keyword. This means the arrays are visible from files other than the one in which they are defined. CNewbie wrote: My Class is CDialog. Does this mean that you are not using MFC? I'm sure you've figured this much out:void (*call_cmd_function[160])(void);
void Func1( void )
{
cout << "Func1" << endl;
}void Func2( void )
{
cout << "Func2" << endl;
}void Func3( void )
{
cout << "Func3" << endl;
}void main( void )
{
call_cmd_function[0] = Func1;
call_cmd_function[1] = Func2;
call_cmd_function[2] = Func3;(\*call\_cmd\_function\[2\])(); (\*call\_cmd\_function\[1\])(); (\*call\_cmd\_function\[0\])();
}
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
CNewbie wrote: What I want to do is define the 2 function pointer arrays with the appropriate functions globally so that I can use them throughout the problem without having to redefine them each time I have to use them. Right. The compiler is never happy when it encounters a redefinition. You can certainly make the arrays global to the entire program. However, they must be initialized within some function (e.g.,
main()
). After that, they can be used from wherever they are needed. And, as you have already discovered, if the arrays are needed in more than one file, you'll need to employ theextern
keyword. This means the arrays are visible from files other than the one in which they are defined. CNewbie wrote: My Class is CDialog. Does this mean that you are not using MFC? I'm sure you've figured this much out:void (*call_cmd_function[160])(void);
void Func1( void )
{
cout << "Func1" << endl;
}void Func2( void )
{
cout << "Func2" << endl;
}void Func3( void )
{
cout << "Func3" << endl;
}void main( void )
{
call_cmd_function[0] = Func1;
call_cmd_function[1] = Func2;
call_cmd_function[2] = Func3;(\*call\_cmd\_function\[2\])(); (\*call\_cmd\_function\[1\])(); (\*call\_cmd\_function\[0\])();
}
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
Actually I am using MFC. "CDialog" is a ficticious name. As I pointed out in the last post, I declared both of the arrays in my header file as such:
void (*call_cmd_function[160])(); void (*call_ins_function[48])();
Then I defined them "globally" at the top of one of my source files as such:void (CflowlogDlg::*call_ins_function[48])() = {NULL}; void (CflowlogDlg::*call_cmd_function[160])() = {NULL};
As you said without the "extern" keyword this would not be seen within all of my source files. The wierd thing is that I reference these arrays in more then one of my source files and the compiler didnt give me any errors when compiling with this code. Now I do define these arrays in my InitDialog() as such:CflowlogDlg INSFunction; INSFunction.call_ins_function[0] = &CflowlogDlg::doins00; INSFunction.call_ins_function[46] = &CflowlogDlg::doins5C;
but when I get to reference the array in another member function it is not defined. Instead of the array having the function addresses in them they have the default memory address of 0xCCCCCCCC in them. The definition only works if i put the definition of the arrays in the same member function as the one I reference them from. Now obviously I am doing something wrong here, but i do not know what -
Actually I am using MFC. "CDialog" is a ficticious name. As I pointed out in the last post, I declared both of the arrays in my header file as such:
void (*call_cmd_function[160])(); void (*call_ins_function[48])();
Then I defined them "globally" at the top of one of my source files as such:void (CflowlogDlg::*call_ins_function[48])() = {NULL}; void (CflowlogDlg::*call_cmd_function[160])() = {NULL};
As you said without the "extern" keyword this would not be seen within all of my source files. The wierd thing is that I reference these arrays in more then one of my source files and the compiler didnt give me any errors when compiling with this code. Now I do define these arrays in my InitDialog() as such:CflowlogDlg INSFunction; INSFunction.call_ins_function[0] = &CflowlogDlg::doins00; INSFunction.call_ins_function[46] = &CflowlogDlg::doins5C;
but when I get to reference the array in another member function it is not defined. Instead of the array having the function addresses in them they have the default memory address of 0xCCCCCCCC in them. The definition only works if i put the definition of the arrays in the same member function as the one I reference them from. Now obviously I am doing something wrong here, but i do not know whatCNewbie wrote: void (*call_cmd_function[160])(); void (*call_ins_function[48])(); Then I defined them "globally" at the top of one of my source files as such: void (CflowlogDlg::*call_ins_function[48])() = {NULL}; void (CflowlogDlg::*call_cmd_function[160])() = {NULL}; Here you have two separate copies of
call_ins_function
andcall_cmd_function
. Arecall_cmd_function
andcall_ins_function
supposed to be a member ofCflowlogDlg
?
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
CNewbie wrote: void (*call_cmd_function[160])(); void (*call_ins_function[48])(); Then I defined them "globally" at the top of one of my source files as such: void (CflowlogDlg::*call_ins_function[48])() = {NULL}; void (CflowlogDlg::*call_cmd_function[160])() = {NULL}; Here you have two separate copies of
call_ins_function
andcall_cmd_function
. Arecall_cmd_function
andcall_ins_function
supposed to be a member ofCflowlogDlg
?
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
See if this helps:
class CflowlogDlg
{
public:void Func1( void ) { cout << "Func1()" << endl; } void Func2( void ) { cout << "Func2()" << endl; } void Func3( void ) { cout << "Func3()" << endl; } typedef void (CflowlogDlg::\*call\_cmd\_function)(void);
};
void main( void )
{
CflowlogDlg::call_cmd_function arr[160];arr\[0\] = CflowlogDlg::Func1; arr\[1\] = CflowlogDlg::Func2; arr\[2\] = CflowlogDlg::Func3; CflowlogDlg m; (m.\*arr\[2\])(); (m.\*arr\[1\])(); (m.\*arr\[0\])();
}
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
See if this helps:
class CflowlogDlg
{
public:void Func1( void ) { cout << "Func1()" << endl; } void Func2( void ) { cout << "Func2()" << endl; } void Func3( void ) { cout << "Func3()" << endl; } typedef void (CflowlogDlg::\*call\_cmd\_function)(void);
};
void main( void )
{
CflowlogDlg::call_cmd_function arr[160];arr\[0\] = CflowlogDlg::Func1; arr\[1\] = CflowlogDlg::Func2; arr\[2\] = CflowlogDlg::Func3; CflowlogDlg m; (m.\*arr\[2\])(); (m.\*arr\[1\])(); (m.\*arr\[0\])();
}
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
That worked as local definitions, but didn't work for the global aspect. The reference of call_cmd_function and call_ins function as well as the class referencein my other source files go unresolved. I can pinpoint my problem to the fact that I need to globalize my class instance. I can lcoalize them by defining them in a member function like so: CflowlogDlg Instance; but again i dont know how to globalize it and extern it so it can be used throughout all of my source files. I tried doing it like I read in the c++ book I have, but it doesnt seen to work correctly as I get Linker errors.
-
That worked as local definitions, but didn't work for the global aspect. The reference of call_cmd_function and call_ins function as well as the class referencein my other source files go unresolved. I can pinpoint my problem to the fact that I need to globalize my class instance. I can lcoalize them by defining them in a member function like so: CflowlogDlg Instance; but again i dont know how to globalize it and extern it so it can be used throughout all of my source files. I tried doing it like I read in the c++ book I have, but it doesnt seen to work correctly as I get Linker errors.
At this point, I suggest you boil the problem down to just what is absolutely necessary. From there you can post a code snippet and we can put it to rest once and for all.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
At this point, I suggest you boil the problem down to just what is absolutely necessary. From there you can post a code snippet and we can put it to rest once and for all.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
Ok I decided to make both arrays static so that I wouldn't have to use any class instances to access them. Plus it boads better for my program to do it this way since all of the member functions that the array uses are already static.Now I know that static variable (even global ones) are only known within the file that it is declared in. Here is what I did: Within my Header file I declare the 2 arrays as static:
static void (*call_cmd_function[160])(); static void (*call_ins_function[48])();
Then I define them at the top of the source files where I reference them:void (CflowlogDlg::*call_cmd_function[160])() = {NULL}; //goes into flowlogcmds.cpp void (CflowlogDlg::*call_ins_function[48])() = {NULL}; //goes into flowlogins.cpp
When I compile I get unresolved external symbol errors:flowlogcmds.obj : error LNK2001: unresolved external symbol "public: static void (__cdecl** CflowlogDlg::call_cmd_function)(void)" (?call_cmd_function@CflowlogDlg@@2PAP6AXXZA) flowlogins.obj : error LNK2001: unresolved external symbol "public: static void (__cdecl** CflowlogDlg::call_ins_function)(void)" (?call_ins_function@CflowlogDlg@@2PAP6AXXZA)
neither are referenced outside of its file, so I dont know why I am getting the Linker errors. -
Ok I decided to make both arrays static so that I wouldn't have to use any class instances to access them. Plus it boads better for my program to do it this way since all of the member functions that the array uses are already static.Now I know that static variable (even global ones) are only known within the file that it is declared in. Here is what I did: Within my Header file I declare the 2 arrays as static:
static void (*call_cmd_function[160])(); static void (*call_ins_function[48])();
Then I define them at the top of the source files where I reference them:void (CflowlogDlg::*call_cmd_function[160])() = {NULL}; //goes into flowlogcmds.cpp void (CflowlogDlg::*call_ins_function[48])() = {NULL}; //goes into flowlogins.cpp
When I compile I get unresolved external symbol errors:flowlogcmds.obj : error LNK2001: unresolved external symbol "public: static void (__cdecl** CflowlogDlg::call_cmd_function)(void)" (?call_cmd_function@CflowlogDlg@@2PAP6AXXZA) flowlogins.obj : error LNK2001: unresolved external symbol "public: static void (__cdecl** CflowlogDlg::call_ins_function)(void)" (?call_ins_function@CflowlogDlg@@2PAP6AXXZA)
neither are referenced outside of its file, so I dont know why I am getting the Linker errors.if
call_cmd_function
,call_ins_function
,doins00
, anddoins5C
are allstatic
members, why put them in a class at all? That's seems to make things unnecessarily complicated. Does this work:class CflowlogDlg
{
public:static void Func1( void ) { cout << "Func1()" << endl; } static void Func2( void ) { cout << "Func2()" << endl; } static void Func3( void ) { cout << "Func3()" << endl; }
};
void (*call_cmd_function[3])(void);
void main( void )
{
call_cmd_function[0] = CflowlogDlg::Func1;
call_cmd_function[1] = CflowlogDlg::Func2;
call_cmd_function[2] = CflowlogDlg::Func3;(\*call\_cmd\_function\[2\])(); (\*call\_cmd\_function\[1\])(); (\*call\_cmd\_function\[0\])();
}
Now you can reference
call_cmd_function[]
from other files, too.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown
-
if
call_cmd_function
,call_ins_function
,doins00
, anddoins5C
are allstatic
members, why put them in a class at all? That's seems to make things unnecessarily complicated. Does this work:class CflowlogDlg
{
public:static void Func1( void ) { cout << "Func1()" << endl; } static void Func2( void ) { cout << "Func2()" << endl; } static void Func3( void ) { cout << "Func3()" << endl; }
};
void (*call_cmd_function[3])(void);
void main( void )
{
call_cmd_function[0] = CflowlogDlg::Func1;
call_cmd_function[1] = CflowlogDlg::Func2;
call_cmd_function[2] = CflowlogDlg::Func3;(\*call\_cmd\_function\[2\])(); (\*call\_cmd\_function\[1\])(); (\*call\_cmd\_function\[0\])();
}
Now you can reference
call_cmd_function[]
from other files, too.
"Ideas are a dime a dozen. People who put them into action are priceless." - Unknown