Segmentation error at the end of the destructor

I don’t know if this question will be clear, since I cannot give too many details (I use TPL and wrote a huge number of lines myself). But I'll try.

I am experiencing a segmentation error that I cannot understand. There is a structure (which I did not develop, but should be well tested), whose destructor is as follows

Data::~Data() { if(A_ != 0) { delete A_; A_ = 0; } if(B_ != 0) { delete B_; B_ = 0; } if(C_ != 0) { delete C_; C_ = 0; } } // HERE 

What bothers me is that when debugging, I get that segfault happens on the line marked “HERE”. The Data class has only A_, B_, and C_ as dynamically allocated attributes. I also tried to explicitly call the destructor on other non-dynamic compound attributes to make sure that something went wrong during their destruction, but again segfault happens at the end of the destructor. What errors can segfault give at this moment ?.

I hope that the question will be clear enough, I will add details if necessary.

Edit: thanks for the answers. I know that this is a damn piece of code, but the whole library is, of course, too large (by the way, it is from Trilinos, but I think that the error is not their fault, it must be my mistake in working with their structures. Short names to make the problem more compact). Some comments that someone asked in the comments:

  • about checks before deleting (s) and raw pointers: as I said, this is not my choice. I assume this is double protection if something goes wrong, and A_, B_ or C_ has already been deleted by another owner of the data structure. The choice of raw pointers against shared_ptr or other safe / smart pointers is probably due to the fact that this class is almost never used directly, but only by an object of the Map class that has a pointer to Data. This class map is implemented in the same library, so they probably chose the source pointers because they knew what they were processing and how.
  • yes, the data structure is shared by all copies of the same object. In particular, there is a Map class that contains a pointer to a Data object. All cards that are copies of each other have the same data. The reference counter keeps track of how many cards a data pointer holds. The last Card to be destroyed will delete the data.
  • the data structure control counter is working correctly, I checked it.
  • I do not call the destructor of this class. It is called automatically by the destructor of an object of the Map class, which has a pointer to the Data as attribute.
  • Data is inherited from BaseData, whose (virtual) destructor does nothing, because it is just an interface that defines a class.
  • It is difficult to publish code reproducing the problem. For many reasons. The error appears only with more than two processes (this is the mpi program), and I assume that the process has some list that is empty and is trying to access some element.
  • about the details of errors. I can give you the last points in the error return path during debugging (I apologize for the poor format, but I don't know how to do this):

    • 0x00007ffff432fba5 in a raise (sig =) in .. /nptl/sysdeps/unix/sysv/linux/raise.c: 64

    • 0x00007ffff43336b0 in abort () on abort.c: 92

    • 0x00007ffff436965b in __libc_message (do_abort =, fmt =) in .. / sysdeps / unix / sysv / linux / libc _fatal.c: 189

    • 0x00007ffff43736d6 in malloc_printerr (action = 3, str = 0x7ffff4447780 "free (): corrupted unsorted pieces", ptr =) in the file malloc.c: 6283

    • 0x00007ffff4379ea3 in __libc_free (mem =) on malloc.c: 3738

    • 0x0000000000c21f71 in Epetra_BlockMapData :: ~ Epetra_BlockMapData (this = 0x1461690, __in_chrg =) in / home / bartgol / LifeV / trilinos / trilinos -10.6.4-src / packages / epetra / src / Epetra_lockP

In conclusion, let me repeat my doubt: what errors can appear in the END of the destructor, even if ALL attributes have already been deleted? Thanks again!

+7
source share
3 answers

One problem that can cause segfault when a function exits is a heap or stack corruption .

It is possible that some other part of your program is causing problems. Something like double destruction or buffer overflows can lead to memory corruption.

Often, debug builds of programs will include a check when exiting a function to make sure that the stack is not corrupted. If it is not, you will see the results.

+3
source

When the explicit body of the class’s destructor completes, it performs some implicit actions: it calls the base class and member destructors (in case you have base classes and members with non-trivial destructors) and, if necessary, it calls the raw memory operator delete function operator delete ( yes, in a typical implementation, operator delete actually called from within the destructor). Apparently, one of these two implicit processes caused a crash in your case. There is no way to say for sure without additional information.

PS Stylistically, the code is terrible. Why do they check for null before doing delete ? What is the zero point of deleted pointers in the destructor?

+2
source

It's hard to tell from the lean code you are showing. You may have already released resources that one of your class members or your base class uses in its own destructor.

0
source

All Articles