Insure++ Reference - VIRTUAL_BAD
This error is caused when a virtual function has not been initialized
prior to being used by another function.
The following pieces of code illustrate this error. The virtual function
func is declared in virtbad1.C in the
goo class. A static variable of this class,
barney , is also declared in that file. The function
crash calls func through barney
in line 23. In file virtbad2.C, a static variable of class
foo, fred , is declared. Class foo
calls crash , which then in turn ends up calling the
virtual function func . A virtual function's address is
not established until the program is initialized at runtime, and static
functions are also initialized at runtime. This means that depending on the
order of initialization, fred could be trying to find
func , which does not yet have an address. The
VIRTUAL_BAD error message is generated when this
code is compiled with Insure++.
Note: Due to differences in th object layout of different compilers.
this error may not be detected with certain compilers.
1: /*
2: * File: virtbad1.C
3: */
4: #include <iostream.h>
5:
6: class goo {
7: public:
8: int i;
9: goo::goo() {
10: cerr << "goo is initialized."
<< endl; }
11: virtual int func();
12: virtual int func2();
13: };
14: static goo barney;
15: int crash() {
16: int ret;
17: cerr << "Sizeof(goo) = " <<
sizeof(goo) << endl;
18: cerr << "Sizeof(i) = " <<
sizeof(int) << endl;
19: char *cptr = (char *) &barney;
20: cptr += 4;
21: long *lptr = (long *) cptr;
22: cerr << "vp = " << *lptr << endl;
23: ret = barney.func();
24: cerr << "crash" << endl;
25: return ret;
26: }
27: int goo::func() {
28: cerr << "goo.func" << endl;
29: func2();
30: return i;
31: }
32: int goo::func2() {
33: cerr << "goo.func2" << endl;
34: return 2;
35: }
Figure 1. virtbad1.C
1: /*
2: * File: virtbad2.C
3: */
4: #include <iostream.h>
5:
6: extern int crash();
7:
8: class foo {
9: public:
10: foo::foo() {
11: cerr << "foo" << endl;
12: cerr << "Got " <<
crash() << endl;
13: }
14: };
15:
16: static foo fred;
Figure 2. virtbad2.C
1: /*
2: * File: virtbad3.C
3: */
4: #include <iostream.h>
5:
6: int main() {
7: cerr << "main" << endl;
8: return 0;
9: }
Figure 3. virtbad3.C
[virtbad1.C:29] **VIRTUAL_BAD**
1. >> func2();
2. Virtual function table is invalid: func2()
3. Stack trace where the error occurred:
goo::func() virtbad1.C, 29
crash() virtbad1.C, 23
foo::foo() virtbad2.C, 12
__mod_I__fred0virtbad21001_cc_000()
_main()
main() virtbad3.C, 6
**Memory corrupted. Program may crash!!**
4. Abort (core dumped)
- Source line at which the problem was detected.
- Description of the problem and which virtual function caused
the error.
- Stack trace showing the function call sequence leading to
the error.
- Core dumps typically follow these messages, as any usage
of the dynamic memory functions will be unable to cope.
The error in the sample code could be eliminated by not making
fred static. In that case, the address for
func would be generated during the initialization
before any requests for it existed, and there would be no problems.
USER_ERROR
WRITE_BAD_INDEX
|