1
\$\begingroup\$

I have written a little program that overwrites memory. It creates useless files in a folder named "folder" (I am so creative). The purpose is to overwrite old data. It's not a very professional program because I am a beginner, but I think it should do for which it is destined: exhaust memory and thus maybe overwrite old data that was stored on it. If you have tips for me how to imrove this program or how to make it faster in it's execution I would be thankful!

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

int create_files(int number_of_files, int number_of_values);

int main()
{
    int number_of_files;
    int number_of_values;

    srand(time(NULL));

    printf("before using this program create a folder with the name \"folder\"\nin the same folder this program is located\n");
    printf("number of files: ");
    scanf("%d", &number_of_files);
    printf("number of values: ");
    scanf("%d", &number_of_values);

    create_files(number_of_files, number_of_values);

}

void create_files(int number_of_files, int number_of_values)
{   
    for(int i = 0; i < number_of_files; i++)
    {
        FILE * file;
        char file_name[30] = "./folder/";
        char file_number[20];
        sprintf(file_number, "%d", i);
        strcat(file_name, file_number);
        file = fopen(file_name, "w+");

        for(int j = 0; j < number_of_values; j++)
        {
            int random_value = rand();
            fprintf(file, "%d", random_value);
        }
        fclose(file);
    }
}
\$\endgroup\$
6
  • \$\begingroup\$ Hrmm... Why are you using char for file_name and file_number? Shouldn't they be string and int respectively? \$\endgroup\$ Commented Jul 14, 2017 at 23:17
  • \$\begingroup\$ Be aware that this doesn't work how you think with SSDs, and will likely shorten their lifetime needlessly. \$\endgroup\$ Commented Jul 15, 2017 at 3:23
  • \$\begingroup\$ @Sometowngeek C does not have a string. You work with char * or char [N]. \$\endgroup\$
    – Zeta
    Commented Jul 15, 2017 at 8:13
  • \$\begingroup\$ In C a string is not a default data type. There is also no composed data type defined in a standard library of C. But with knowledge string handling in C is also not a witchcraft. \$\endgroup\$ Commented Jul 15, 2017 at 11:40
  • \$\begingroup\$ Oop. I learned something new. \$\endgroup\$ Commented Jul 16, 2017 at 17:52

1 Answer 1

1
\$\begingroup\$

Make a habit of initializing variables. Your scanfmight fail:

scanf("%d", &number_of_files);

What happens if I answer "many"? Well, first of all, scanf will return 0, and next number_of_files won't get changed. So its value is unknown. If we use it, we end up with undefined behaviour, which is a fancy term to say "we have no idea what will happen".

So in order to at least prevent something like number_of_files = 1000000000 and number_of_values = 10000000 just because the input failed, make sure to initialize your values and maybe check whether scanf succeeded:

int main()
{
    int number_of_files  = 0;
    int number_of_values = 0;

    srand(time(NULL));

    printf("before using this program create a folder with the name \"folder\"\nin the same folder this program is located\n");
    printf("number of files: ");

    if(scanf("%d", &number_of_files) != 1) {
       // handle the error?
    }
    printf("number of values: ");

    if(scanf("%d", &number_of_values) != 1) {
       // handle the error?
    }

    create_files(number_of_files, number_of_values);
}

Note that your usage is misleading: the folder has to be located in the folder the program is run, not located.

Let the compiler help you

Note that I got rid of the int i? You declared it, but you've never used it. You probably had all of your program in your main and decided to refactor (good!), but you forgot not only the i, but to return something in create_files. Both of these mishaps could have been found with compiler flags:

$ gcc -Wall -pedantic main.c

main.c: In function 'int main()':    
main.c:10:9: warning: unused variable 'i' [-Wunused-variable]    
     int i;    
         ^    
main.c: In function 'int create_files(int, int)':    
main.c:44:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }    
 ^

Initialize the seed once

I've moved the srand call into main. That way there will be only one call to srand, regardless of how many times you call create_files. That's handy since

  • we can now reconstruct the flow if we print the seed
  • we can reconstruct the flow even if we call create_files multiple times
  • we don't have to worry about calling create_files twice in the same second

Simplify and continue to check errors

You can use sprintf to print your file_name directly:

char file_name[50] = "";
sprintf(file_name, "./folder/trash-%015d");

This will format file_name as "./folder/trash-000000000000001". Since every file name has the same length, the sorting is somewhat better, and the trash- prefix will simplify the users life in case they accidentally had a folder called folder (but they should really rename that folder).

That being said, you should check whether you were able to open that file at all, and whether you could actually write to it. Remember, you're trying to fill a disk (not memory) to the brim. If it's full, you cannot continue to write, and either fopen or fprintf will fail:

if(!(file = fopen(file_name, "w+")))
{
    perror("Could not open file");
    return i;
}

for(int j = 0; j < number_of_values; j++)
{
    int random_value = rand();
    if(fprintf(file, "%d", random_value) < 0)
    {
        fclose(file);
        return i;
    }
}

Note that I return i because I think you've wanted to return the number of created files, but I'm not sure. If you didn't want to return anything at all, change create_files return type to void.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you very much for your tips! Yes, i first wanted to write it all in the main function, but then it looked a little bit unordered und so have written a second function and forgot to delete the variable i. The function should be of type "void", i will correct this. \$\endgroup\$ Commented Jul 15, 2017 at 11:32
  • \$\begingroup\$ @DexterThorn As already mentioned in a comment on the question, please do not correct the code in the question. The original code should not be updated. Optionally you can open a new question and link between them. \$\endgroup\$ Commented Nov 23, 2017 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.