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); }
(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].
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); }
No problem. How about point 2 and the thing about 16 byte strings, which you seem to have completely missed, or ignored.
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.
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.
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); }
I tried changing the line to Code: char index[256] ; and when I tried compiling, my strtok returns a char* not an array.
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.
; 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); }
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.
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; }
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
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.
i have run it on Mac. I have tried it without threads and it makes no difference. I answered all of your questions.
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.