I'm writing a C code to open txt file and read two lines on it then print the value
it worked for 1018 time then it gives "Segmentation fault"
I've tried to flush the buffer but it don't work
while(running) {
i = 0;
if ((fptr = fopen("pwm.txt", "r")) == NULL) {
printf("Error! File cannot be opened.");
// Program exits if the file pointer returns NULL.
exit(1);
}
fptr = fopen("pwm.txt","r");
while (fgets(line,sizeof(line), fptr)){
ppp[i]=atoi(line);
i++;
}
fclose(fptr);
printf("%d %d\n",ppp[0],ppp[1]);
rc_servo_send_pulse_us(ch, 2000);
rc_usleep(1000000/frequency_hz);
}
Actually, the file-opening is the likely culprit: On e.g. Linux there's a limit to how many files you can have open, and it typically defaults to 1024. A few files are used for other things, and your program probably uses some other file-handles elsewhere, leaving only around 1018 left over.
So when you open the file twice, you leak the file handle from the first fopen call, and then your second fopen call will fail and give you a NULL pointer in return. And since you don't check for NULL the second time you attempt to use this NULL pointer and have a crash.
Simple solution: Remove the second and unchecked call to fopen.
Related
I made the file "wor.txt" in the same program and i closed its write stream. But when i try to access it in first run(I created the file) it gives segmentation fault but when i re-run this program it runs successfully.
When i delete the automatically generated file and run the program again it gives Segmentation fault and on 2nd run(Without deleting the file) it runs successfully again.
NOTE: There is data in the textfile hence it is not empty(I have seen it after the first run in the file manager)
FILE *fp1= fopen("wor.txt","r");
FILE *f1= fopen("wordsa.txt","ab+");
if((f1==NULL)||(f2==NULL)){
printf("f1 or f2 is null");
}
char c='0';
while((c)!=EOF){
printf("Here is one marker\n");
c=fgetc(fp1); //This Line gives error
printf("Here is another marker\n");
fputc(c,f1);
}
A char is no sufficient for EOF, change the type to int.
Check the man page of fgetc(), it returns an int and you should use the same datatype for storing the return value and further use.
That said, when either of f1 or fp1 is NULL, you are continuing anyways, accessing those file pointers, which may create UB. You should make some sense of that NULL check and either return or exit so that the code accessing tose pointers are not reached.
Incorrect check.
To properly detect opening of the stream, check fp1, not f2. Then code will fail gracefully when the files do not open properly rather than seg fault.
FILE *fp1= fopen("wor.txt","r");
FILE *f1= fopen("wordsa.txt","ab+");
// if((f1==NULL)||(f2==NULL)){
if((f1==NULL) || (fp1==NULL)){
printf("f1 or fp1 is null");
}
Also use int c as fgetc() typically returns 256 + 1 different values (unsigned char values and EOF) and a char is insufficient to uniquely distinguish them.
This seems to be a really simple one, but I can't figure it out after not touching C programming in four years.
I was trying to open a file in main()
int main(int argc, const char * argv[])
{
FILE * fp = fopen("data.txt","r");
...
return(0)
}
The program compiled, but when I tried to run it in gdb, the following error occurs.
Program received signal SIGSEGV, Segmentation fault.
0x00000000004016c6 in main ()
when the program is trying to open the file "data.txt". What could cause the error? Thanks!
I suspect your error lies in this bit of code:
...
In other words, there's nothing in the other code shown that appears to be wrong.
The most likely case is that the file doesn't exist, or it doesn't exist in the directory where the program is running (which, if you're in an IDE, usually turns out to be somewhere other than you think it is).
And, in that case, you're getting NULL from the fopen, then later using it, something like:
FILE *fp = fopen ("no_such_file.txt", "r");
int ch = fgetc (fp);
You should generally check return values from all functions that use them to indicate success or failure:
#include <stdio.h>
int main (void) {
FILE *fp = fopen ("no_such_file.txt", "r");
if (fp == NULL) {
perror ("Opening no_such_file.txt");
return 1;
}
// You can use fp here.
puts ("It worked.");
fclose (fp);
return 0;
}
What could cause the error?
The most likely cause of the error is that the file data.txt could not be opened (e.g. because it doesn't exist, or it's not in the current directory, or your program doesn't have permission to read it). That will cause fopen() to return NULL. Then if your code (in the ... section) tries to call fread() or fgets() or whatever and passes in the NULL pointer, that will cause a crash. You need to check the value returned by fopen() to make sure it is non-NULL before trying to use it.
I've been trying simple file handling in C and I wanted to make sure that the file can be accessed tried using this
#include<stdio.h>
main()
{
CheckFile();
}
int CheckFile()
{
int checkfile=0;
FILE *fp1;
fp1 = fopen("users.sav","r");
if(fp1==NULL)
{
fopen("users.sav","w");
fclose(fp1);
}
if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);
return 0;
}
then it displays
Segmentation fault (core dumped)
but it doesn't segfault if the file already exists beforehand (e.g. when i created it manually or when i run the program the second time)
Please help. I need this for our final project due in a week and I haven't gotten the hang of files and pointers yet.
I'm using "gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1"
P.s
I saw this in another question
There's no guarantee in your original code that the fopen is actually working, in which case it will return NULL and the fclose will not be defined behaviour.
So how exactly do I check if it worked?
That's normal, when you call fclose(fp1) when fp1 is NULL.
BTW
fopen("users.sav","w");
is useless because you don't assign the return value to a file pointer. That means the users.sav file will be opened for writing, but you will never be able to write anything in it .
fopen returns a FILE pointer. It will return NULL and set the global errno to indicate the error. If you want to check the errno, you have to check if after you check if fopen returned NULL.
if (fp1 == NULL)
{
printf("fopen failed, errno = %d\n", errno);
}
Otherwise, you may get an errno from something else, not necessarily your fopen call. Also include errno.h. You also don't need to call fopen("users.sav","w"); again. You aren't reassigning the pointer nor checking it again.
I don't see a reason to call fclose here since if fopen returns NULL, there isn't anything to close. That is probably the reason for your seg fault. You are trying to close a null pointer. More information on fopen failures.
Another comment on your code. If you are going to return an int from CheckFile, it should probably not be 0 on fail. I would return -1 to indicate an error. Better yet, you could return the global errno. Also, main should be int main() and you should return 0; at the end. I don't particularly care for your naming scheme of CheckFile. In C, check_file or camelCase of checkFile would be better.
In CheckFile, your one line if statement could be formatted and work more properly if you formatted it on multiple lines. It doesn't do what you think it does currently:
if(checkfile!=0)
{
printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n", checkfile);
exit(1);
}
Also, checkfile is never set anywhere in your code.. other than zero. So the code in the if statement will not execute, period.
I'm not really sure what you're trying to do, but the immediate problem is here:
if(fp1==NULL)
fclose(fp1);
After asserting that fp1 is NULL, you're trying to call close on the null pointer, which will cause a segmentation fault.
If all you want to do is verify that the file exists, try something like What's the best way to check if a file exists in C? (cross platform)
The man page of fclose says -
The behaviour of fclose() is undefined if the stream parameter is an
illegal pointer, or is a descriptor already passed to a previous
invocation of fclose().
The error is in the if block in your code.
if(fp1==NULL)
{
fopen("users.sav","w");
fclose(fp1); // passing NULL to fclose invokes undefined behaviour
}
Another unrelated problem:
This line is probably not what you want:
if(checkfile!=0)printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);exit(1);
If we write it correctly formatted the error becomes obvious:
if (checkfile != 0)
printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);
exit(1);
return 0 ;
Actually we will get to exit(1) even if checkfile is zero.
You probably want this:
if (checkfile != 0)
{
printf("\nERROR ACCESSING FILE!\nNow exiting program with exit code: %d\n",checkfile);
exit(1);
}
return 0 ;
Conclusion: format your code correctly and many errors will suddenly look obvious.
I have a random access file opened in "r+b" mode with records of equal length. Can I change the contents of a record after reading it and overwrite in place?
I tried the following code but on running I get: Segmentation fault(core dumped)
#include<stdio.h>
int main()
{
struct tala {
int rec_no;
long file_no;
};
FILE *file_locking;
struct tala t,f;
file_locking = fopen("/path/to/my/file.bin", "rb+");
t.rec_no = 1;
t.file_no = 3;
if (fwrite(&t, sizeof(struct tala),1,file_locking)==0)
printf("Error opening file");
t.rec_no=0;
rewind(file_locking);
if (fwrite(&t, sizeof(struct tala),1,file_locking)==0)
printf("Error opening file");
rewind(file_locking);
if (fread(&f, sizeof(struct tala),1,file_locking)==0)
printf("Error opening file");
printf("\n %d",f.rec_no);
printf("\n %ld", f.file_no);
fclose(file_locking);
}
Yes you can. Just remember to always fseek between reads and writes.
Quote the fopen man page:
Reads and writes may be intermixed on read/write streams in any order. Note that ANSI C requires that a file positioning function intervene between output and input, unless an input operation encounters end-of-file.
Extra tip: always check the return value of fopen and related functions, and handle errors (use perror or strerror to print out what failed).
Yes. The only thing to pay attention is that you have to call flush or a file positioning function before switching from output to input and call a file positioning function or be at end of file before switching from read to write.
fclose() is causing a segfault. I have :
char buffer[L_tmpnam];
char *pipeName = tmpnam(buffer);
FILE *pipeFD = fopen(pipeName, "w"); // open for writing
...
...
...
fclose(pipeFD);
I don't do any file related stuff in the ... yet so that doesn't affect it. However, my MAIN process communicates with another process through shared memory where pipeName is stored; the other process fopen's this pipe for reading to communicated with MAIN.
Any ideas why this is causing a segfault?
Thanks,
Hristo
Pass pipeFD to fclose. fclose closes the file by file handle FILE* not filename char*. With C (unlike C++) you can do implicit type conversions of pointer types (in this case char* to FILE*), so that's where the bug comes from.
Check if pepeFD is non NULL before calling fclose.
Edit: You confirmed that the error was due to fopen failing, you need to check the error like so:
pipeFD = fopen(pipeName, "w");
if (pipeFD == NULL)
{
perror ("The following error occurred");
}
else
{
fclose (pipeFD);
}
Example output:
The following error occurred: No such file or directory
A crash in fclose implies the FILE * passed to it has been corrupted somehow. This can happen if the pointer itself is corrupted (check in your debugger to make sure it has the same value at the fclose as was returned by the fopen), or if the FILE data structure gets corrupted by some random pointer write or buffer overflow somewhere.
You could try using valgrind or some other memory corruption checker to see if it can tell you anything. Or use a data breakpoint in your debugger on the address of the pipeFD variable. Using a data breakpoint on the FILE itself is tricky as its multiple words, and is modified by normal file i/o operations.
You should close pipeFD instead of pipeName.