What can cause a segmentation error with the delete command in C ++?

I wrote a program that allocates a new object of class T as follows:

T* obj = new T(tid); 

where tid is int

Somewhere else in my code, I am trying to free an object I selected that is inside a vector using:

 delete(myVec[i]); 

and then:

 myVec[i] = NULL; 

Sometimes it passes without any errors, and in some cases it causes failures - segmentation error.

I checked before calling delete, and this object is there - I have not deleted it elsewhere.

What could cause this crash?
This is my code for inserting objects of type T into a vector:

 _myVec is global int add() { int tid = _myVec.size(); T* newT = new T (tid); if (newT == NULL){ return ERR_CODE; } _myVec.push_back(newT); // _myVec.push_back(new T (tid)); return tid; } 

as is - the program sometimes crashes.
When I replace the push_back line with a commented line and leave the rest as is, it works.

but when replacing this code:

 int add() { int tid = _myVec.size(); if (newT == NULL){ return ERR_CODE; } _myVec.push_back(new T (tid)); return tid; } 

he crashes at another stage ...

newT is not used in the second variant and still - changes the whole process ... what is happening here?

+7
source share
5 answers

Segfaulting means trying to manipulate a memory location that should not be accessible to the application.

This means that your problem can arise from three cases:

  • Trying to do something with a pointer pointing to NULL;
  • Trying to do something with an uninitialized pointer;
  • Trying to do something with a pointer pointing to a now deleted object;

1) it is easy to check, so I assume that you already do this when you invalidate pointers in a vector. If you do not perform checks, do this before calling the delete. This will indicate when you are trying to delete an object twice. 3) cannot happen if you set NULL to a pointer in a vector.

2) may also occur. In your case, you are using std :: vector, right? Make sure that implicit vector manipulations (for example, reallocating the internal buffer when it is not big enough) do not damage your list.

So, first check that you are deleting NULL pointers (note that delete (NULL) will not throw! This is the standard and correct behavior!) - in your case, you should not get to the point of trying to delete (NULL). Then, if this does not happen, make sure that you do not fill the vector with pointers pointing to the basket. For example, you should make sure that you are familiar with [Remove-Erase idiom] [1].


Now that you have added the code, I think I see the problem:

 int tid = _myVec.size(); 

You use the index as identifiers.

Now it depends on how you delete your objects. (please show it for a more complete answer)

  • You just pointed to a NULL pointer.
  • You are removing the pointer from the vector.

If you only do 1) then it should be safe (unless you worry about a vector that grows and never gets free, and identifiers are not reused).
If you do 2. then this is all wrong: every time you delete an object from a vector, the whole object remains after the position of the deleted object is dropped by one. Invalid invalid id / index.

Make sure you are consistent at this point; this is definitely a source of errors.

+10
source

most likely a segmentation error and memory access violation. Some reasons

1) the object is already freed. make sure you set this position to NULL after deletion 2) you are outside the bounds of the array 3) if you are accessing this array from multiple threads, make sure you synchronize correctly

0
source

If you are completely sure that the pointer points to a valid object and that the action of deleting it will fail, then you have heap corruption.

0
source

You should try using ptr_vector , unlike your code, it is guaranteed to be safe.

Hint: if you write delete , you are doing it wrong

0
source

You cannot be sure that the object is still valid: the memory that was occupied by the object is not necessarily cleared, and therefore you can see something that seems to be your object, but this is no longer the case.

You can use the sign to make sure that the object is still alive, and remove this mark in the destructor.

 class A { public: static const unsigned int Inactive; static const unsigned int Active; A(); ~A(); /* more things ...*/ private: unsigned int mark; }; const unsigned int A::Inactive = 0xDEADBEEF; const unsigned int A::Active = 0x11BEBEEF; A::A() : mark( Active ) {} A::~A() { mark = Inactive; } 

Thus, by checking the first 4 bytes in your object, you can easily check if your object has ended live or not.

0
source

All Articles