I don't know if this question is going to be clear, since I can't give too many details (I'm using a TPL and wrote a huge amount of lines myself). But I'll give it a try.
I am experiencing a segmentation fault which I can't understand. There is a structure (which I didn't design but should be well tested) whose destructor looks like this
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's bothering me is that, while debugging, I get that the segfault happens at the line marked with 'HERE'. The class Data has only A_, B_ and C_ as dynamically allocated attributes. I also tried to explicitly call the destructor on the other non-dynamic composite attributes, to see if something went wrong during their destruction, but again the segfault happens at the end of the destructor. What kind of errors can give a segfault at that point?.
I hope the question is clear enough, I will add details if needed.
Edit: thanks for the replies. I know it's a scarse piece of code, but the whole library is of course too big (it comes from Trilinos, by the way, but I think the error is not their fault, it must be my mistake in handling their structures. I used short names to keep the problem more compact). Some remarks that somebody asked in the comment replies:
- about the checks before the delete(s) and the raw pointers: as I said, it's not my choice. I guess it's a double protection in case something goes wrong and A_, B_ or C_ has been already deleted by some other owner of the data structure. The choice raw-pointers vs 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 class Map that has a pointer to Data. This class Map is implemented in the same library, so they probably chose raw pointers since they knew what they were handling and how.
- yes, the data structure is shared by all the copies of the same object. In particular, there is a Map class that contains a pointer to a Data object. All the Map's that are copies of one each other, share the same Data. A reference counter keeps track of how many Map's are holding a pointer to the data. The last Map to be destroyed, deletes the data.
- the reference counter of the Data structure works correctly, I checked it.
- I am not calling the destructor of this class. It is called automatically by the destructor of an object of class Map that has a pointer to Data as attribute.
- Data inherits from BaseData, whose (virtual) destructor doesn't do anything, since it's just an interface defining class.
- It's hard to post the code that reproduce the problem. For many reasons. The error appears only with more than 2 processes (it's an mpi program), and my guess it that a process has some list that is empty and tries to access some element.
about the error details. I can give you here the last items in the backtrace of the error during debugging (I apologize for the bad format, but I don't know how to put it nicely):
0x00007ffff432fba5 in raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
0x00007ffff43336b0 in abort () at abort.c:92
0x00007ffff436965b in __libc_message (do_abort=, fmt=) at ../sysdeps/unix/sysv/linux/libc_fatal.c:189
0x00007ffff43736d6 in malloc_printerr (action=3, str=0x7ffff4447780 "free(): corrupted unsorted chunks", ptr=) at malloc.c:6283
0x00007ffff4379ea3 in __libc_free (mem=) at malloc.c:3738
0x0000000000c21f71 in Epetra_BlockMapData::~Epetra_BlockMapData ( this=0x1461690, __in_chrg=) at /home/bartgol/LifeV/trilinos/trilinos-10.6.4-src/packages/epetra/src/Epetra_BlockMapData.cpp:110
To conclude, let me restate my doubt: what kind of errors can appear AT THE END of the destructor, even if ALL the attributes have been deleted already? Thanks again!