I am having a very weird error, I would try to run valgrind, but I am on OS X Yosemite, so this is not possible. I am getting a segfault with an fopen, it seems before the fopen is ever even called. I have a function called format:
void format(uint16_t sector_size, uint16_t cluster_size, uint16_t disk_size)
{
FILE *fp;
fp=fopen(diskName, "wb");
if(fp != NULL)
{
printf("Disk successfully initialized at: %s",diskName);
}
else
{
printf("There was an error creating the disk.");
return;
}
for(int i=0;i<disk_size;i++)
{
fwrite(0, sizeof(sector_size), cluster_size, fp);
}
}
Diskname is declared globally at the top of the file:
char diskName[32];
Here is my main:
int main(int argc, char *argv[]) {
strcpy(diskName, "test.bin");
printf("%s",diskName);
format(128, 8, 1000);
}
The weird part is that, this code segfaults before it ever prints the diskname:
Run Command: line 1: 16016 Segmentation fault: 11
I have no idea how this is possible, and I've tried a wide-array of solutions, but it all boils down to an error with fopen. When fopen is commented out the code runs. Any idea why this would happen?
printf will buffer its output until you flush the output. This can be done by either printing a newline, or flushing the output using fflush(stdout).
In any case, your error is here:
fwrite(0, sizeof(sector_size), cluster_size, fp);
You may not see your program crash when you comment out the fopen call because the fwrite call will fail earlier. fwrite's signature expects a pointer to the data to write as the first argument, where you have provided zero. This will cause fwrite to attempt to dereference a NULL pointer and thus crash.
You can either allocate a buffer, set it all to zero, then write that to the file using fwrite, e.g.
char* buf = calloc(cluster_size, sector_size); // Remember, calloc initialises all elements to zero!
fwrite(buf, sector_size, cluster_size, fp);
Or just call fputc in a loop
for(int i = 0; i < sector_size * cluster_size; i++)
fputc(0, fp);
Also, sizeof(sector_size) will always return 2 in your example, as you're taking the size of the type. Are you sure this is correct?
Related
I am trying to write a function to read an input from a separate file in C, and arrange this data for further processing. I am, however, running into a segmentation fault when i am trying to assign values to int variables.
The code looks like this:
void read_file1 (char *filename, int *numTrees)
{
int tempNum;
char tempStr[1000];
char line;
FILE *filer;
filer = fopen(filename, "r");
fgets(tempStr, 1000, filer);
sscanf(tempStr, "numTrees: %i numLeaves: %i", numTrees, &tempNum);
/*
More Code
*/
}
void read_file2 (char *filename, int *numTrees, int *numLeaves)
{
char tempStr[1000];
char line;
FILE *filer;
filer = fopen(filename, "r");
fgets(tempStr, 1000, filer);
sscanf(tempStr, "numTrees: %i numLeaves: %i", numTrees, numLeaves); //Segmentation fault occurs here
/*
More Code
*/
}
int main()
{
char *filename = "datainput.txt";
int *numTrees, *numLeaves;
read_file2(filename, numTrees, numLeaves);
return 0;
}
The two different read_file functions are meant to arrange the data in different formats. The read_file1 functions works as intended, yet when i try to use a largely identical setup in read_file2, i get a segmentation fault from the sscanf. The problem seems to lie with the assignment of a value to numTrees, as attempting to assign a value separately also triggers a segmentation fault.
Which is strange, seeing as the nearly identical read_file1 works fine.
Can anyone tell the issue that is causing the error?
At least this is wrong in your code (a very common beginner's error):
int *numTrees, *numLeaves; // those pointers are not initialized
read_file2(filename, numTrees, numLeaves);
instead you want this:
int numTrees, numLeaves;
read_file2(filename, &numTrees, &numLeaves); // provide the pointers
// to the int variables
// numTrees and numLeaves
Also a check for fopen is mandatory:
filer = fopen(filename, "r");
if (filer == NULL)
{
printf("Fatal erorr, file does not exist\n");
exit(1);
}
This will abort program if the files not not exist. In real world programs a more sophisticated error handling should be done, but here at least we eliminate the chance of reading from an invalid FILE pointer.
I'm trying to read a binary file of 32 bytes in C, however I'm keep getting "segmentation fault (code dumped)" when I run my program,
it would be great if somebody can help me out by pointing where did I go wrong?.
my code is here below:
int main()
{
char *binary = "/path/to/myfiles/program1.ijvm";
FILE *fp;
char buffer[32];
// Open read-only
fp = fopen(binary, "rb");
// Read 128 bytes into buffer
fread (buffer, sizeof(char), 32, fp);
return 0;
}
It's because of the path. Make sure that "/path/to/myfiles/program1.ijvm" points to an existing file.
You should always check the return value of fopen.
\\Open read-only
fp = fopen(binary, "rb");
if(fp==NULL){
perror("problem opening the file");
exit(EXIT_FAILURE);
}
Notice also that you are reading 32 bytes in your buffer and not 128 as your comment says.
You must check the return result from fopen().
I'm assuming you are getting the segfault in the fread() call because your data file doesn't exist, or couldn't be opened, and you are trying to work on a NULL FILE structure.
See the following safe code:
#include <stdio.h>
#include <stdint.h>
#define SIZE_BUFFER 32
int main()
{
char *binary = "data.txt";
FILE *fp = NULL;
char buffer[SIZE_BUFFER];
// Open read-only
fp = fopen(binary, "rb");
// Read SIZE_BUFFER bytes into buffer
if( fp )
{
printf("Elements read %ld\n", fread (buffer, sizeof(char), SIZE_BUFFER, fp));
fclose(fp);
}
else
{
// Use perror() here to show a text description of what failed and why
perror("Unable to open file: ");
}
return 0;
}
When I execute this code it doesn't crash and will print the number of elements read if the file is opened or it will print "Unable to open file" if the file could not be opened.
As mentioned in the comments you should also close the file being exiting. Another thing you can do is the following:
FILE *fp = fopen(.....);
Instead of declaring and assigning in two separate steps.
There are two possible reasons
The fopen(3) function failed due to some reason, which means fp is NULL, and then you are trying to use the null-pointer in fread(3). This can crash. #OznOg has already given a subtle hint to look into this direction.
If the fopen call is a success (i.e. fp is non-NULL after calling fopen), the code can still crash because you are reading 32 chars into the variable binary, while binary has been initialized with only 30 chars.
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 am working on a simple C program to open a file and read some data from it. There are no compile errors, but when I run the program on a certain file, I get a "Segmentation Fault: code dumped" error. I inserted a print statement at the very top of my code, and it does not get run. Is it possible to get a segmentation fault when you haven't done anything yet?
#include <stdio.h>
int main(int argc, char **argv)
{
printf("%s", "Made it to here!");
FILE *fp;
char input[100];
fp = fopen(argv[1], "r+b");
fgets(input, sizeof(input), fp);
printf("%s", input);
fclose(fp);
return(0);
}
This works when I run it on the text version of itself, it prints out the first line. However, when I run it on another file, texttest.vmf, I get the segmentation fault and the first print doesn't execute. VMFs are Valve Map Files, but they're in standard text format. This file is about 3.7 KB large. Any ideas?
It is not necessary that your code fails before printf: the call to printf may have succeeded, but because the output to console is buffered, the program may have crashed before the output has been written to the screen.
Adding \n to the output string causes console buffer flush. If you are looking to debug by printfs, you should always add \n to the end of your format string.
Your fopen call is likely failing. Try checking the return value before you attempt to use fp:
FILE *fp;
char input[100];
if((fp = fopen(argv[1], "r+b") == NULL) {
fprintf(stderr, "ERROR: Cannot open file.\n");
return 1;
}
Make sure to add #include <stdlib.h> for use of the NULL macro.
I don't know exactly why a file pointer reads an extra line from a file, specifically the last line, here is the code:
FILE *fp ;
fp = fopen ("mac_ip.txt", "r") ;
int mac;
char *ip = (char *) malloc(15);
while(!feof(fp)){
fscanf(fp,"%i",&mac);
fscanf(fp,"%s",ip);
printf("MAC: %i\n",mac);
printf("IP: %s\n",ip);
}
and the file has exactly 20 lines, but the line 20, is printed twice.
Which is the error?
Thanks in advance.
Because after reading the last two values, you still haven't hit EOF. So the loop goes on. In the next pass of the loop, fscanf actually does not read the last line for the second time like it appears, the fscanfs fail, but the printfs print out the values from the previous pass of the loop.
feof does not "know" it's at the end of file until you try to read some more. Since fscanf tells you how many items it got, you can use this simple trick:
for(;;){
if (fscanf(fp,"%i%s", &mac, ip) != 2) break;
printf("MAC: %i\n",mac);
printf("IP: %s\n",ip);
}
After you have done the two reads on the twentieth line, you have got to the end of the file but the system doesn't know this. feof will only trigger when you try to get past the end of the file, not when you are exactly on it ...
Also, you may have a line-end (CR or CR-LF) on the 20th line which it will only get past with another attempted read.
The solution is to read the line in one go (there is a specific C command for this) and then parse that to get your data. If the whole-line read fails, then you've got to the end.
Your code resembles to the following example
#include <stdio.h>
int main(void)
{
char buffer[256];
FILE * myfile;
myfile = fopen("some.txt","r");
while (!feof(myfile))
{
fgets(buffer,256,myfile);
printf("%s",buffer);
}
fclose(myfile);
return 0;
}
from
http://www.friedspace.com/feof.html
You better test for fscanf return value before printing result. I bet that in the last iteration of your loop, fscanf calls fail and you print the last returned results.
FILE *fp ;
int mac;
char ip[15];
fp = fopen ("mac_ip.txt", "r") ;
if (!fp) return;
while(1){
if (fscanf(fp,"%i",&mac) < 1) break;
if (fscanf(fp,"%s",ip) < 1) break;
printf("MAC: %i\n",mac);
printf("IP: %s\n",ip);
}
fclose (fp);
fscanf() returns the number of assignments it mad (or -1 on eof). By using the return value, you don't need the eof() function. BTW I don't think you can read a MAC address into an int. Maybe you need to read that into a string, too ?
Explanation: feof() does not do what the OP expects. feof() should only be inspected after one of the file operations failed. In most cases you don't need feof().