#256 Virtual functions in destructor

Josh Coalson
libFLAC++ (6)

Hello! Sorry, english is not my best language.

I use libFLAC++ API. I have some problems. In libFLAC API all OK.

Unhandled exception at 0x00000000 in Test.exe: 0xC0000005: Access violation reading location 0x00000000.

Call stack
Test.exe!FLAC::Encoder::File::progress_callback_(const FLAC__StreamEncoder * encoder=0x003571f8, unsigned __int64 bytes_written=2156194, unsigned __int64 samples_written=845544, unsigned int frames_written=734, unsigned int total_frames_estimate=0, void * client_data=0x0012fe1c) Line 507 + 0x2a bytes C++
Test.exe!file_write_callback_(const FLAC__StreamEncoder * encoder=0x003571f8, const unsigned char * buffer=0x0047daa8, unsigned int bytes=2804, unsigned int samples=1128, unsigned int current_frame=733, void * client_data=0x0012fe1c) Line 4487 + 0x7a bytes C
Test.exe!write_frame_(FLAC__StreamEncoder * encoder=0x003571f8, const unsigned char * buffer=0x0047daa8, unsigned int bytes=2804, unsigned int samples=1128, int is_last_block=1) Line 2712 + 0x3a bytes C
Test.exe!write_bitbuffer_(FLAC__StreamEncoder * encoder=0x003571f8, unsigned int samples=1128, int is_last_block=1) Line 2622 + 0x19 bytes C
Test.exe!process_frame_(FLAC__StreamEncoder * encoder=0x003571f8, int is_fractional_block=1, int is_last_block=1) Line 3119 + 0x16 bytes C
Test.exe!FLAC__stream_encoder_finish(FLAC__StreamEncoder * encoder=0x003571f8) Line 1334 + 0xf bytes C
Test.exe!FLAC::Encoder::Stream::~Stream() Line 57 + 0xc bytes C++
Test.exe!FLAC::Encoder::File::~File() Line 448 + 0x8 bytes C++
Test.exe!MyFile::~MyFile() + 0x2e bytes C++
Test.exe!main() Line 188 + 0xf bytes C++
Test.exe!__tmainCRTStartup() Line 586 + 0x19 bytes C
Test.exe!mainCRTStartup() Line 403 C

void File::progress_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
FLAC__ASSERT(0 != client_data);
File *instance = reinterpret_cast<File *>(client_data);
FLAC__ASSERT(0 != instance);
instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate); // Here!!! progress_callback = 0

I think about this problem (am i right?):

The C++ Programming Language Special Edition (Third Edition) Bjarne Stroustrup

15.4.3 Class Object Construction and Destruction
A class object is more than simply a region of memory (§4.9.6). A class object is built from ‘‘raw
memory’’ by its constructors and it reverts to ‘‘raw memory’’ as its destructors are executed. Construction
is bottom up, destruction is top down, and a class object is an object to the extent that it
has been constructed or destroyed. This is reflected in the rules for RTTI, exception handling
(§14.4.7), and virtual functions.
It is extremely unwise to rely on details of the order of construction and destruction, but that
order can be observed by calling virtual functions, dynamic_ cast, or typeid (§15.4.4) at a point
where the object isn’t complete. For example, if the constructor for Component in the hierarchy
from §15.4.2 calls a virtual function, it will invoke a version defined for Storable or Component,
but not one from Receiver, Transmitter, or Radio. At that point of construction, the object isn’t
yet a Radio; it is merely a partially constructed object. It is best to avoid calling virtual functions
during construction and destruction.

Email address: visor@nextmail.ru


  • Logged In: NO

    An Excerpt from Effective C++, Third Edition
    by Scott Meyers
    June 6, 2005

    Item 9: Never call virtual functions during construction or destruction

    Email address: visor@nextmail.ru

  • Josh Coalson
    Josh Coalson

    • priority: 5 --> 6
    • assigned_to: nobody --> jcoalson
    • status: open --> open-accepted
  • Josh Coalson
    Josh Coalson

    • priority: 6 --> 8
  • Ralph Giles
    Ralph Giles

    • status: open-accepted --> closed
    • Group: --> 1.3.0