Why does this fread segfault - c

I have tried many things to fix this segfault issue, I'm not sure whats happening wrong because from my understanding, the fread line should not segfault
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: ./recover file");
return 1;
}
char* recover = argv[1];
// open input file
FILE * raw_file = fopen(recover, "r");
if (raw_file == NULL)
{
fprintf(stderr, "Could not open %s.\n", recover);
return 2;
}
//somehow read the file
int counter = 1;
char file[2];
sprintf(file,"%03i.jpg",counter);
int buffer[512];
//read file and put into buffer
int*bf = malloc(sizeof(int));
fread(bf, sizeof(int), 1, raw_file);

you smashed you stack in this block prior to your fread
char file[2];
sprintf(file,"%03i.jpg",counter);
file is to small to hold the number of characters you are formatting into it.

Related

C error: program is free of memory errors, valgrind tests failed

I am doing the CS50 PSet 4 Recover problem and get the below error:
program is free of memory errors
valgrind tests failed; see log for more information.
I don't understand what is the error, and therefore not sure how to fix it. I've tried using the debugger but it doesn't help.
My code is the below:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(int argc, char *argv[])
{
// Check number of arguments
if (argc != 2)
{
printf("Only one argument should be used\n");
return 1;
}
// Open reading file
FILE *input_file = fopen(argv[1], "r");
if (input_file == NULL)
{
printf("Could not open file.\n");
return 2;
}
// Store blocks of 512 bytes in an array
BYTE buffer[512];
// Keep track of number of images generated
int count_image = 0;
// File pointer for recovered images
FILE *output_file = NULL;
// Char filename
char *filename = malloc (8 * sizeof(char));
// Read the blocks of 512 bytes
while (fread(buffer, sizeof(char), 512, input_file))
{
// Check if the bytes indicate start of JPEG
if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0)
{
// Write the JPEG filenames
sprintf(filename, "%03i.jpg", count_image);
// Open output file for writing
output_file = fopen(filename, "w");
// Count number of images found
count_image++;
}
if (output_file != NULL)
{
fwrite(buffer, sizeof(char), 512, output_file);
}
}
free(filename);
fclose(output_file);
fclose(input_file);
return 0;
}
Can someone please explain what I'm doing wrong? Valgrind says there's an error with the line:
output_file = fopen(filename, "w");
But where in your code would you close 50 files? You open them in a loop but only close once after the loop. You must close the old file whenever you open a new one. Otherwise the pointer to the old FILE structure is lost and you can never close the file resulting in 49 memory leaks.

fread not writing to ptr

I'm trying to read the contents of a file with fread, however the contents are not being written to the ptr. I've verified with the ftell() function that the position in the stream is changing, however no content is written to the ptr.
I've implemented the same functionality in another code, the only difference being that in that case it was a struct instead of char *, I can't figure out based on the documentation why this is the case.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
// ensure proper usage
if (argc != 2)
{
fprintf(stderr, "Usage: recover infile\n");
return 1;
}
char *infile = argv[1];
// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
fprintf(stderr, "Could not open %s.\n", infile);
return 2;
}
char *block;
block = malloc(sizeof(char)*64);
fread(block, 1, 64, inptr);
printf(" es %s \n", block);
int position = ftell(inptr);
printf("position %d \n", position);
free(block);
fclose(inptr);
}
The malloc is currently a placeholder btw.
Any explanations as to why the data on the file isn't being written to block?
In general, if you want to understand better what is the output of a printf, you could write:
printf("Test: <%s> - (len=%lu)\n", block, strlen(block));

C - Two processes reading the same file

I have a function that reads a file and returns an integer. There are two processes that use this same function and I am getting a segmentation fault.
Read function:
int getNumberFromFile() {
FILE* fp;
char* line;
fp = fopen(fileName, "rb");
fgets (line, 10, fp);
fclose(fp);
return atoi(line);
}
function Usage:
pid_t pid = fork();
if (pid == 0) {
struct process p1;
p1.processId = getpid();
printf("N: %d, PID: %d", getNumberFromFile(), p1.processId);
}
else if (pid > 0 ) {
struct process p2;
p2.processId = getpid();
printf("N: %d, PID: %d", getNumberFromFile(), p2.processId);
}
else {
printf("Error: Could not create process\n");
}
Is it not possible for two different processes to read the same file at the same time? If not how would I give one process the precedence so that other function can perform the read function afterwards?
Your issue has nothing to do with threads.
char* line;
fgets (line, 10, fp);
You are writing to uninitialized memory.
You need to allocate some storage behind the "line" pointer. Just change the declaration to char line[10].
Ps. There are no problems reading a file from multiple processes.
Your problem will occur whether you have one or two processes using the function; the function is faulty. You've not allocated any space to read the line into:
int getNumberFromFile()
{
FILE* fp;
char* line; // Uninitialized pointer
fp = fopen(fileName, "rb"); // Unchecked - errors possible
fgets(line, 10, fp); // Unchecked - and bad news if fopen() failed
fclose(fp); // Bad news if fopen() failed
return atoi(line);
}
You seem to want:
int getNumberFromFile(const char *fileName)
{
FILE *fp = fopen(fileName, "rb");
int rv = 0;
if (fp != 0)
{
char line[10];
if (fgets(line, sizeof(line), fp) != 0)
rv = atoi(line);
fclose(fp);
}
return rv;
}
This doesn't use uninitialized variables or null pointers, both of which can cause crashes.

runtime-error "access violation writing location " with strcpy function

i have this run time error "access violation writing location " with strcpy function
Here part of my code:
else if (strcmp(sentenceRecv, "405002") == 0){
/*winVersion[SIZE] = (char*)malloc(sizeof(tempString));*/
system("ver >> text.txt");
FILE *pfile = fopen("text.txt", "rt+");
if (pfile == NULL)
{
printf("Couldn't open file\n");
}
fread(tempString, sizeof(char), SIZE - 1, pfile);
fclose(pfile);
pfile = fopen("text.txt", "w");
if (pfile == NULL)
{
printf("Couldn't open file\n");
}
fputc((int)' ', pfile);
fclose(pfile);
/* winVersion[SIZE] = strdup(tempString);*/
strcpy(winVersion, tempString);
send(ClientSocket, winVersion, sizeof(winVersion), 0);
menuCheck = 1;
}
The error is in this line:strcpy(winVersion, tempString);
and in the first lines i write:
char winVersion[SIZE];
char tempString[SIZE];
char tempString[SIZE] = {0};
strcpy() needs a null-terminated string ('\0')
Otherwise it will just keep going until it hits a '\0' somewhere in the contiguous memory which may not belong to your program hence the access violation error.
You could use char *strncpy(char *dest, char *src, size_t n); and specify SIZE as the n number of bytes to copy. This is still somewhat unsafe because the copied strings won't be null-terminated either and could cause more problems later.
http://beej.us/guide/bgc/output/html/multipage/strcpy.html

Why wont the program read from the 2 argument file?

So the assignment is to implement a substring search program using an input file to be searched from and an input to be searched. I created the following code:
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp;
fp = fopen(argv[1],"r");
if (fp == NULL)
{
printf("Error");
return 0;
}
char* tmpp[100];
int count = 0;
char* nexts = argv[2];
char* tmp = fgets(tmpp,100,fp);
while(tmp = strstr(tmp,nexts))
{
count++;
tmp++;
}
printf("%d\n\n",count);
fclose(fp);
return 0;
}
The program compiles but when i go to implement it in the ubuntu terminal as:
echo "aabb" >beta
./a.out beta a
1
Why isnt the program using the first argument (argv[1]) as beta and the second argument (argv[2]) as a correctly?
You should open a file and then read bytes from that file into temporary buffer:
FILE *file = fopen("file", "r");
while (1) {
char buffer[BUFSIZ+1];
size_t nread = fread(buffer, 1, sizeof(buffer)-1, file);
if (nread == 0) break; // read error or EOF
buffer[nread] = 0;
// chunk with BUFSIZ amount of bytes is available via buffer (and is zero-terminated)
}
If you want to search for string/pattern in a file, be aware that looked pattern in file may cross your chunk-size boundary, for example: you look for "hello", and BUFSIZ is 512. File contains "hello" at byte 510. Obviously, if you read by 512, you will get the first chunk ending with "he", and the second chunk starting with "llo". Probability of this situation is nonzero for all chunk sizes (except SIZE_MAX, but that buffer size is impossible by other reasons). Dealing with borders may be very complicated.
Close...but this is closer:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: %s file pattern\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
fprintf(stderr, "Error: failed to open file %s for reading\n", argv[1]);
return 1;
}
char tmpp[1000];
int count = 0;
char* nexts = argv[2];
while (fgets(tmpp, sizeof(tmpp), fp) != 0)
{
char *tmp = tmpp;
while ((tmp = strstr(tmp, nexts)) != 0)
{
count++;
tmp++;
}
}
printf("%d\n", count);
fclose(fp);
return 0;
}
The main difference is that this loops reading multiple lines from the input file. Yours would only work on files with a single line of input.

Resources