Search code examples
cfileio

Writing doesn't stop for files above ~2gb in C


I have some C code that is supposed to generate a password and save it to a file. I tried to enter a length that would be about 10 gb (absurdly big but I wanted to see how fast it could do it), and it didn't stop at 10 gb.

#define _FILE_OFFSET_BITS 64
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(){
    int i = 0;
    char chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_-+={[]}\\|;:'\",<.>/?`~!@#$^&*()";
    long long size;
    char keypath[512];
    char password;
    printf("Where should the key be saved? ");
    fgets(keypath, sizeof(keypath), stdin);
    keypath[strcspn(keypath, "\n")] = 0;
    printf("How long should the key be? ");
    scanf("%lli",&size);
    getchar();
    srand((unsigned int)(time(NULL)));
    FILE* fptr = fopen(keypath,"a");
    if (fptr == NULL) {
        printf("Failed to open file for writing\n");
        return 1;
    }
    for (i = 0; i < size; i++){
        int choice = rand() % strlen(chars);
        password = chars[choice];
        fprintf(fptr, "%c", chars[choice]);
    }
    fclose(fptr); 
    return 0;
}

It seems like when it goes somewhere over 1 gib (I assume 2 gib since that's the regular amount it goes to before using #define _FILE_OFFSET_BITS 64) it doesn't stop writing and instead keeps going seemingly indefinitely.

I am using Raspbian.

Any help is much appreciated.


Solution

  • It is good that you made the variable size to be of the type long long, so that it is guaranteed to be able to represent a file size of 10 GB.

    However, you forgot to do the same with the variable i. Instead, you gave i the data type int.

    Due to this, the loop

    for (i = 0; i < size; i++){
        int choice = rand() % strlen(chars);
        password = chars[choice];
        fprintf(fptr, "%c", chars[choice]);
    }
    

    will invoke undefined behavior due to signed integer overflow, unless you happen to be on a platform on which int is able to represent a file size of 10 GB. On most common PC platforms, INT_MAX (which is the maximum value an int can represent) has a value of 2147483647. On those platforms, an int is unable to represent the value 10000000000.