Seg Fault Mem Leak

Discussion in 'C++' started by mmoose68, Jun 23, 2009.

  1. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    Alright, this function is in a thread which is reading lines from a file which will never be longer than 16 chars. inside the while(1) loop, if I comment out everything except an output of ptrr and the fgets, there is no seg fault. Also, I can comment out the push_backs and I still get the seg fault. Can someone please help me figure this one out?
    Code:
    void * read_file(void*){
    	FILE * oar1 ;
    	oar1 = fopen("/dev/ttyT8S0","r");
    	char *ptrr = new char[16] ;
    	char *index = new char[16] ;
    	char *value = new char[16] ;
    	long ind = 0 ;
    	long vl = 0 ;
    	while(1){
    		fgets(ptrr, 16, oar1);
    		if(atoi(ptrr)!=0){
    			index = strtok(ptrr,",");
    			value = strtok(NULL,", ");
    			ind = strtol(index,NULL,16);  vl = strtol(value,NULL,16);
    			identifier.push_back(ind);
    			vals.push_back(vl);
    			cout<<ind<<" - "<<vl<<endl;
    		}
    	}
    	fclose(oar1);
    	
    }
     
    Last edited by a moderator: Jun 24, 2009
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    (1) Please use code blocks.
    (2) The problem may not be in the code you've posted. Create a testbed that calls this from a simple main() function and make sure that reproduces the problem. If it does then post the new code here WITH CODE BLOCKS and we can have a look.

    Out of interest, does the maximum line length of 16 characters include room for end of line and terminating NULL? So if you have the string "Hello\n" for example, that's actually 7 characters, and if you mean the "Hello" part is limited to 16 characters then you need larger arrays than just [16].
     
  3. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    Sorry about that.

    Code:
    void * read_file(void*){
    	FILE * oar1 ;
    	oar1 = fopen("/dev/ttyT8S0","r");
    	char *ptrr = new char[16] ;
    	char *index = new char[16] ;
    	char *value = new char[16] ;
    	long ind = 0 ;
    	long vl = 0 ;
    	while(1){
    		fgets(ptrr, 16, oar1);
    		if(atoi(ptrr)!=0){
    			index = strtok(ptrr,",");
    			value = strtok(NULL,", ");
    			ind = strtol(index,NULL,16);  vl = strtol(value,NULL,16);
    			identifier.push_back(ind);
    			vals.push_back(vl);
    			cout<<ind<<" - "<<vl<<endl;
    		}
    	}
    	fclose(oar1);
    	
    }
     
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    No problem. How about point 2 and the thing about 16 byte strings, which you seem to have completely missed, or ignored.
     
  5. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    Alright I did everything from point 2 you mentioned. Same result. The segfault happens after about 20 seconds of reading the file. Yes, 16 is plenty as the actual line is 14 chars.
     
  6. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    The memory leak could be the cause; you new[] three character arrays but you don't delete[] them. This isn't Java and you don't get a free garbage collector. I'm not sure why you want to use new/delete here anyway;
    Code:
    char ptrr[16];
    
    is perfectly valid in this scenario, and since this is automatic you don't have to worry about cleanup, and this is likely a lot faster than digging around in the heap.
     
    shabbir likes this.
  7. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    Alright, I have played with more options and now have this. It is still giving a seg fault
    Code:
    void * read_file(void*){
    	FILE * oar1 ;
    	oar1 = fopen("/dev/ttyT8S0","r");
    	char ptrr[256] ;
    	char *index = new char[256] ;
    	char *value = new char[256] ;
    	long ind = 0 ;
    	long vl = 0 ;
    	while(1){
    		fgets(ptrr, 256, oar1);
    		if(atoi(ptrr)!=0){
    			index = strtok(ptrr,",");
    			value = strtok(NULL,", ");
    			ind = strtol(index,NULL,16);  vl = strtol(value,NULL,16);
    			identifier.push_back(ind);
    			vals.push_back(vl);
    			cout<<ind<<" - "<<vl<<endl;
    		}
    	}
    	fclose(oar1);
    	
    }
     
  8. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Code:
    char ptrr[256] ;
    char *index = new char[256] ;
    
    Not paying attention?
     
  9. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    I tried changing the line to
    Code:
    char index[256] ;
    and when I tried compiling, my strtok returns a char* not an array.
     
  10. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Whoops, sorry, turns out it's me not paying attention. So index and value don't need initialising at all, since they take on values returned by strtok. This also explains why you leak 512 bytes each time the function is called, which could be why you get a segfault.
     
  11. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    So this means the line should look as follows:

    Code:
    char *index
    ??
    Thanks.
     
  12. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Almost. What do all C statements end with?
     
  13. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    ;

    So, if that is the answer to your question... I am still getting a segfault after reading a lot of values from the file. The new code is as follows:

    Code:
    vector<long> vals;
    vector<long> identifier;
    
    void * read_file(void*){
    	FILE * oar1 ;
    	oar1 = fopen("/dev/ttyT8S0","r");
    	//oar1 = fopen("./RawData.txt","r");
    	char ptrr[20] ;
    	char *index ;
    	char *value ;
    	long ind = 0 ;
    	long vl = 0 ;
    	while(1){
    		fgets(ptrr, 20, oar1);
    		if(atoi(ptrr)!=0){
    			index = strtok(ptrr,",");
    			value = strtok(NULL,", ");
    			ind = strtol(index,NULL,16);  vl = strtol(value,NULL,16);
    			identifier.push_back(ind);
    			vals.push_back(vl);
    			cout<<ind<<" - "<<vl<<endl;
    		}
    		
    	}
    	fclose(oar1);
    	
    }
     
  14. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    How many is "a lot", and what are, say, the first 10 rows of RawData.txt?
    Can you reproduce the problem if RawData.txt is long enough (and you use it instead of /dev/ttyT8S0, of course)? How do you generate RawData.txt?
    Do you still get a segfault if you comment out the two push_back lines?

    What versions of what OS and compiler are you using?

    Edit:
    Also I asked this before: "Create a testbed that calls this from a simple main() function and make sure that reproduces the problem."
    Obviously if I just try to build the above program on my computer I'll get a "missing symbol: main" error.
     
  15. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    So, /dev/ttyT8S0 is a file which reads from a COM port so the file has no end. It varies as to how long it takes for the segfault but never happens in under 1800 lines of reading. It seems to happen at the fgets line as it does not get past that when it segfaults.

    If I comment out the push_backs, I still get the seg fault.

    I am using a single board computer running debian and g++ 3.3.5

    Code:
    
    #include <stdio.h>
    #include <iostream>
    #include <vector>
    #include <string>
    #include <fstream>
    #include <sstream>
    #include <istream>
    #include <pthread.h>
    #include <cstdlib>
    
    //#include "gnuplot_i.hpp"
    
    using namespace std;
    vector<long> vals;
    vector<long> identifier;
    
    void * read_file(void*){
    	FILE * oar1 ;
    	oar1 = fopen("/dev/ttyT8S0","r");
    	//oar1 = fopen("./RawData.txt","r");
    	char ptrr[20] ;
    	char *index ;
    	char *value ;
    	long ind = 0 ;
    	long vl = 0 ;
    	while(1){
    		fgets(ptrr, 20, oar1);
    		if(atoi(ptrr)!=0){
    			index = strtok(ptrr,",");
    			value = strtok(NULL,", ");
    			ind = strtol(index,NULL,16);  vl = strtol(value,NULL,16);
    			identifier.push_back(ind);
    			vals.push_back(vl);
    			cout<<ind<<" - "<<vl<<endl;
    		}
    		
    	}
    	fclose(oar1);
    	
    }
    
    int main()
    {
    	pthread_t thrd ; 
    	//cout<<"here";
    	int iReturnValue1 = pthread_create(&thrd,0, read_file, NULL);
    	pthread_join(thrd,NULL);
    return 0;
    }
    
     
  16. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    also, the format of the file is as follows:

    1906,20000D81
    1907,20000AF5
    1908,20000B49
    1909,20000A95
    190A,20000AE9
    190B,20000BC5
    190C,20000C51
    190D,20000C11
    190E,20000BED
    190F,20000BE5
     
  17. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    Well, I don't have your hardware, and you don't seem to be interested in answering questions about calling the code directly from main without using threads, using a text file instead of the COM port and so on, so I'm pretty much stuck in terms of being able to help further.

    Have you tried running it under any other OS to see if it's something fundamentally wrong with the code?

    My plan was to run it in Visual Studio 2008 on a WinXP box using a text file to simulate COM input but you need to simplify the code right down before I can do that. No point me doing that only to find there's then no problem.
     
  18. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    i have run it on Mac. I have tried it without threads and it makes no difference. I answered all of your questions.
     
  19. mmoose68

    mmoose68 New Member

    Joined:
    Jun 23, 2009
    Messages:
    13
    Likes Received:
    0
    Trophy Points:
    0
    It does not seem to segfault as fast on the Mac but that does not help me much
     
  20. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    No you didn't. You haven't answeredf the following questions:
    1. Just call it from main. Here's your main code:
    Code:
    int main()
    {
    	pthread_t thrd ; 
    	//cout<<"here";
    	int iReturnValue1 = pthread_create(&thrd,0, read_file, NULL);
    	pthread_join(thrd,NULL);
    return 0;
    }
    
    and here's what I mean by just calling it from main without using threads:
    Code:
    int main()
    {
    	read_file();
    return 0;
    }
    
    - if that works, of course, and it may not, so you need to write this and make sure it still reproduces the problem.

    2. How many is "a lot", and what are, say, the first 10 rows of RawData.txt?

    3. Can you reproduce the problem if RawData.txt is long enough (and you use it instead of /dev/ttyT8S0, of course)?

    4. How do you generate RawData.txt?

    5. Do you still get a segfault if you comment out the two push_back lines? (Clarification: I know you said you did earlier, which is why I asked this time if you STILL get a segfault.)

    It's up to you of course but this is my last post on this thread if I don't get answers. If you won't work with me why should I bother, that's my question.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice