I'm trying to create a program that reads a file (from *argv[]
) into memory, then outputs to terminal.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
FILE *fp;
fp = fopen(argv[1], "r");
unsigned long size;
fseek(fp, 0, SEEK_END);
size = ftell(fp);
rewind(fp);
//printf("\n");
int *dict = malloc(size);
unsigned long i;
for (i = 0; i <= size; i)
*(dict i) = getc(fp);
for (i = 0; i <= size - 1; i)
printf("%c", *(dict i));
free(dict);
return 0;
}
After compiling and running the program, it returns malloc(): corrupted top size
. Uncommenting printf("\n");
will allow the program to work as intended.
CodePudding user response:
This will work: I changed the part of malloc, that was defined int before, (The int* exceeds the memory allocete) also, you read the dict with "%c" so that i converted it to char*.
Also added check for fseek() if returns error, we exit!
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
unsigned long size;
FILE* fp = fopen(argv[1], "rb");
if (fp != NULL) {
if( fseek(fp, 0, SEEK_END) ){ // sets the file position of the SEEK_END
fclose(fp);
return -1;
}
size = ftell(fp); // got size
} else {
return -1; // file not found!
}
char *dict = malloc(size);
unsigned long i;
for (i = 0; i <= size; i)
*(dict i) = getc(fp);
for (i = 0; i <= size-1; i)
printf("%c", dict[i]); // changed for better readability
free(dict);
fclose(fp);
return 0;
}
References:
How do you determine the size of a file in C?
Reading a file using argc and argv
CodePudding user response:
There are multiple problems in your code:
- you open the file in text mode, hence the value returned by
ftell()
is not guaranteed to be the length of the file. - you do not test for
fopen
failure. - you allocate an array of
int
with a byte size ofsize
. This array is way too short to storesize
bytes, one per entry. You should instead allocate an array ofchar
, possibly with a length ofsize 1
to allow for a null terminator. - you do not test for allocation failure.
- the loop
for (i = 0; i <= size; i)
iterates once too far. You readsize 1
bytes from the file. If the array had been allocated aschar *dict = malloc(size);
you would still have undefined behavior. - the output loop writes one byte at a time in an inefficient way. You should just use
fwrite
.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "missing argument\n");
return 1;
}
FILE *fp = fopen(argv[1], "rb");
if (fp == NULL) {
fprintf(stderr, "cannot open %s: %s\n", argv[1], strerror(errno));
return 1;
}
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
if (size < 0) {
fprintf(stderr, "cannot determine file size %s: %s\n",
argv[1], strerror(errno));
fclose(fp);
return 1;
}
char *dict = malloc(size 1);
if (dict == NULL) {
fprintf(stderr, "cannot allocate memory: %s\n", strerror(errno));
fclose(fp);
return 1;
}
size_t nread = fread(dict, 1, size, fp);
if (nread != size) {
fprintf(stderr, "only read %zu/%zu bytes\n", nread, size);
}
dict[nread] = '\0';
size_t nwritten = fwrite(dict, 1, nread, fp);
if (nwritten != nread) {
fprintf(stderr, "only wrote %zu/%zu bytes\n", nwritten, nread);
}
fclose(fp);
free(dict);
return 0;
}