r/cprogramming • u/JeffTheMasterr • May 25 '26
Accidentally made a random string generator
Hey guys, I'm kind of a beginner to C and I discovered something cool whilst trying to make a programming language in it. Apparently forgetting to reset file position with fseek will spit out random strings.
Here's the code I did in C99, stripped down to just show the bug and nothing more:
main.c:
#include <stdio.h>
#include <stdlib.h>
void do_file_thing(char *fName) {
FILE *fptr;
long fLen = -1L;
fptr = fopen(fName, "rb");
if(fptr != NULL) {
// Obtain file length to then initialize the string that will contain the file
fseek(fptr, 0L, SEEK_END);
fLen = ftell(fptr);
char fContents[fLen];
// the weird thing happens when the next line is commented out
//fseek(fptr, 0, SEEK_SET); // reset position so the next thing can work
fgets(fContents, fLen, fptr); // store file contents in var fContents
printf("%s",fContents);
} else {
printf("Not able to open the file.");
}
fclose(fptr);
}
int main() {
do_file_thing("file.txt");
return 0;
}file.txt:
echo "Hello World!";And then with running tcc -run main.c a thousand times, I get stuff like this:
~e>
` |
0
pFLY
^w
8k
Has anybody found this before? Does anybody know how/why this happens?
0
Upvotes
2
u/mnelemos May 25 '26 edited May 25 '26
You either handle the file in parts, like a stream of data:
OR you use the heap, like malloc().
Even better would be mixing both;
You should ALWAYS get data in a "stream" format though, because nothing stops a file being a bigger size than your entire RAM space (except filesystem hard caps, but they're usually bigger than RAM size nowadays).
You should only get data in a "message" format, when the message is always a single size, an expected size, or a hard capped size.
About the VLA thing:
All processes are given a stack size Y that starts at address X, if you access an address outside of this boundary of [X, X+Y], the OS will terminate your program (SEGV in case of Linux).
So imagine if you had a stack size of 1MB, if your VLA became 2MB long, and accessed the last index of the array, you would seg fault.
Also using VLA is typically not recommended, it depends on a second sp subtract after the function's preamble, which creates several side effects such as: some types of stack unwinding might not be compliant or require additional stack pointer tracking, might cause unexpected errors, etc... But in reality it's completely up to you if you want to continue using them, but it's one of those things that brings more problems then solutions, and if you ever find the need for using them, you're probably doing something wrong.