Connecting Tech Pros Worldwide Forums | Help | Site Map

Segmentation Fault : Delete[]

Expert
 
Join Date: Jan 2008
Location: York
Posts: 179
#1: Jan 17 '08
I've got a segmentation fault problem and am wondering if anyone can help me. I'll apologise now for the fact that I've about a week experience using C++, but I'll try my best to follow any replies :)

Firstly I'm developing in C++ on a Linux machine (using g++ compiler).

My application iterates through a process around about 120 times during testing. It appears that I randomly receive segmentation faults during one of these iterations though sometimes I'll reach the end fine. I've believe I've managed to track the problem using a Linux debug tool:

"#3 0x0806d1cf in Heap::Deallocate() (this=0x43001520) at Heap.cpp:40"

I believe Heap is a custom made class, and the appropriate method is:


Expand|Select|Wrap|Line Numbers
  1. 37 void Heap::Deallocate ()
  2. 38 {
  3. 39  if (m_HeapData)
  4. 40    delete[] m_HeapData;
  5. 41  if (m_Indexes)
  6. 42    delete[] m_Indexes;
  7. 43  if (m_FreeSlots)
  8. 44    delete[] m_FreeSlots;
  9. 45
  10. 46  Initialise () ;
  11. 47}
which suggests the delete[] m_HeapData; line. Where
Expand|Select|Wrap|Line Numbers
  1. HeapData* m_HeapData ;
and HeapData is another class.

I am struggling to grasp why this would fail sometimes and not others and would appreciate any guidance. If there is any more information that's useful please let me know. If I've not given enough code for an example, let me know what else might be useful.

Thanks for the help.

Just thought that the creation of m_HeapData may be useful...

Expand|Select|Wrap|Line Numbers
  1. void Heap::Create (int size)
  2. {
  3.   assert (m_HeapData == 0) ;
  4.  
  5.   // Number of slots available (can be extended)
  6.   m_nMax = size ;
  7.  
  8.   // Create the arrays needed for the heap
  9.   m_HeapData = new HeapData [m_nMax] ;
  10.   m_Indexes = new int [m_nMax] ;
  11.   m_FreeSlots = new int [m_nMax] ;
  12.   ....
  13. }
Ian

Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,382
#2: Jan 17 '08

re: Segmentation Fault : Delete[]


Probably because nin Heap::Deallocate() the deleted pointers are notr set ot zero after they are deleted. Should the method be called again, you will crash immediately.

The code should look like:
Expand|Select|Wrap|Line Numbers
  1. void Heap::Deallocate ()
  2. {
  3.      delete[] m_HeapData;
  4.      delete[] m_Indexes;
  5.      delete[] m_FreeSlots;
  6.      m_HeapData = 0;
  7.      m_Indexes = 0;
  8.      m_FreeSlots = 0;
  9.  
  10.   Initialise () ;
  11. }
  12.  
You don't need to check for zero before deleting. This isn't C.

Also, m_ does not make these variables member variables. They are member variables if you use the this pointer:
Expand|Select|Wrap|Line Numbers
  1. void Heap::Deallocate ()
  2. {
  3.      delete[] this->HeapData;
  4.      delete[] this->Indexes;
  5.      delete[] this->FreeSlots;
  6.      this->HeapData = 0;
  7.      this->Indexes = 0;
  8.      this->FreeSlots = 0;
  9.  
  10.   Initialise () ;
  11. }
  12.  
Also, this is not a destructor. Therefore, you can't delete unless you know you are deleting the final copy of thse pointers. And you can't tell that. You should not be using naked pointers here. You should be using reference counted handles (a.k.a. managed or smart pointers). Theres is an article on handles in the C/C++ HowTos. Inside that article is ta template for a referecne counted handle that you can copy and use in your own code. If you do this, your errors will go away.
Expert
 
Join Date: Jan 2008
Location: York
Posts: 179
#3: Jan 17 '08

re: Segmentation Fault : Delete[]


weaknessforcats, thanks for the reply. I've looked at your remarks, and I believe that it does this if I provide a little more detail that now seems more important.

The Deallocate() method is only called from the destructor of Heap if the first thing, there are no references to it anywhere else. Secondly the Initialise method is as follows:

Expand|Select|Wrap|Line Numbers
  1. void Heap::Initialise ()
  2. {
  3.   m_HeapData = 0 ;
  4.   m_Indexes = 0 ;
  5.   m_FreeSlots = 0 ;
  6.   m_nFree = 0 ;
  7.   m_nNum = 0 ;
  8.   m_nMax = 0 ;
  9.   m_nHeapTotal = 0 ;
  10.   m_nHeapPeak = 0 ;
  11. }
  12.  
So it should also reset all those values to 0. Honestly looks a bit of a strange way to do things to me, but I didn't write it so will have to deal with it.
Expert
 
Join Date: Jan 2008
Location: York
Posts: 179
#4: Jan 18 '08

re: Segmentation Fault : Delete[]


I've got an extension to this question if you don't mind...

The stacktrace reports that the problem lies within a DLL that has been used for sometime in the Heap::Deallocate() method I'm led to believe. This DLL operates to carry out 2 different function:

1) The first function works and has been running for several months without problem. It uses the Heap object in the following manner:

Expand|Select|Wrap|Line Numbers
  1. Heap heap ;
  2. HeapData data ;
  3. ... 
  4. heap.Insert(data) ;
  5.  
2) The second function which hasn't been used frequently uses a different approach, opting for the 'new' keyword like so. And later uses delete[] to free the resources up.

Expand|Select|Wrap|Line Numbers
  1. Heap used by Isochrone:
  2. Heap* m_pIsoHeap ;
  3. m_pIsoHeap = new Heap ;
  4.  
When delete[] is called, the destructor is used and within the destructor the Deallocate method is called. If the 'new' keyword isn't used, does this mean that when C++ deals with the memory management, that the destructor will not get called, and hence the deallocate method will never be used?

If this is the case, then the I believe the Deallocation code may not be thread safe, and hence causing me some problems! :)

Can anyone confirm if this way of thinking is correct? Thanks very much.
Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,382
#5: Jan 18 '08

re: Segmentation Fault : Delete[]


Destructors are called when an object goes out of scope. However, an object allocated by new newver goesout of scope. The pointer might, but not the object. You have to manually call delete to remove the object.

Regardless of the method of removal (stack objecty going out of scope or you calling delete), the destructor will be called so you can clean up any allocated data members.

You just need to be certain in that destructor that you don't clean up something you didn't allocate. That means deleting a pointer you go from somewhere inside a destructor is a big no-no.

You need to use handles.
Newbie
 
Join Date: Mar 2008
Posts: 1
#6: Mar 13 '08

re: Segmentation Fault : Delete[]


I have got the segmentation fault problem and I am wondering if anyone can help me.

Firstly I'm developed in C++ on a Linux machine (using g++ compiler).
I am going to develop the Visual Surveillance application using the Network Camera as a hardware.

Program No. 1:

if (mysql_query(conn, "truncate video")) {
//fprintf(stderr, "%s\n", mysql_error(conn));
// exit(0);
}
/* end of MySQL */

if(argc>1){

long current=0;
CURL *curl;
char filename[200];
sprintf(filename,"temp%d.jpg",videoNumber);
FILE *file;
curl_global_init(CURL_GLOBAL_ALL);

curl = curl_easy_init();
char buf[200];
//printf("Test %s\n",inpFile);
if(strlen(inpFile)==2)
{
if(curl){

curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
/* get the first document */
sprintf(buf,"http://root:amol@1234@172.21.107.207/axis-cgi/jpg/image.cgi?resolution=320x240");
curl_easy_setopt(curl, CURLOPT_URL,buf);
int i=0;
CallAR.CallBackActivityReco(inpFile,dumpDir,doorfi le,videoNumber);
while(!signaled){
file=fopen(filename,"w");
curl_easy_setopt(curl,CURLOPT_WRITEDATA,file);
curl_easy_perform(curl);
fclose(file);

//printf("Test\n");
IplImage *NtwkImage=cvLoadImage(filename,1);
current++;
char buffer[50];
sprintf(buffer,"dumpDir/%010d.jpg",current);
//printf("Test\n");
if(!CallAR.frame_call(inpFile,dumpDir,NtwkImage,co nn,videoNumber)) break;
cvReleaseImage(&NtwkImage);
}
curl_easy_cleanup(curl);
}
}
else{
CallAR.CallBackActivityReco(inpFile,dumpDir,doorfi le,videoNumber);
IplImage* I=0;
while(!signaled){
if(!CallAR.frame_call(inpFile,dumpDir,I,conn,video Number)) break;
}
}
exit(0);
}
return 0;
}

and


Program No. 2:

int CallBackAR::frame_call(char* inpFile, char* dumpDir,IplImage* NtwkImage,MYSQL *conn,int vno){
//printf("TESTING\n");
timeval tim;
double t1,t2;
if(strlen(inpFile)==1)
{
gettimeofday(&tim, NULL);
t1=tim.tv_sec+(tim.tv_usec/1000000.0);
image = useStreamer();
gettimeofday(&tim, NULL);
t2=tim.tv_sec+(tim.tv_usec/1000000.0);
//printf("%.6lf Before Grab Time\n", t1);
//printf("%.6lf After Grab time\n", t2);

}

else if(strlen(inpFile)==2)
{
gettimeofday(&tim, NULL);
t1=tim.tv_sec+(tim.tv_usec/1000000.0);
image=NtwkImage;
//pthread_mutex_lock (&mutexsum);
//image=cvLoadImage("image.cgi?resolution=320x240",1 );
//pthread_mutex_unlock (&mutexsum);
gettimeofday(&tim, NULL);
t2=tim.tv_sec+(tim.tv_usec/1000000.0);

//printf("%.6lf Before Grab Time\n", t1);
//printf("%.6lf After Grab time\n", t2);
}
else{
gettimeofday(&tim, NULL);
t1=tim.tv_sec+(tim.tv_usec/1000000.0);

if( !cvGrabFrame( capture )) return 0;
cimage = cvRetrieveFrame(capture);
gettimeofday(&tim, NULL);
t2=tim.tv_sec+(tim.tv_usec/1000000.0);
//printf("%.6lf Before Grab Time\n", t1);
//printf("%.6lf After Grab time\n", t2);
cvResize(cimage,image);
}


Please help me as early as possible since I have solve this issue today.
Moderator
 
Join Date: Mar 2007
Location: North Bend Washington USA
Posts: 5,382
#7: Mar 13 '08

re: Segmentation Fault : Delete[]


Quote:

Originally Posted by madanear

I have got the segmentation fault problem and I am wondering if anyone can help me.

I would like to but this is IanWright's post.

Start your own thread, please, rather than hijack someone else's.
Reply