Compare commits

..

No commits in common. "main" and "v1.1.0" have entirely different histories.
main ... v1.1.0

2 changed files with 42 additions and 207 deletions

View file

@ -1,24 +1,22 @@
# memory allocator # memory allocator
it allocates memory it allocates memory *(in gibibytes (GiB))*
## how to use ## how to use
``` - run the executable
usage: allocatememory -b <bytes> [-o <output file>] [-s] - enter how many gibibytes you want (max is how many gibibytes of memory you have)
- confirm (y)
OPTIONS - wait for the program to allocate the memory
-h displays help - your memory is allocated
-b number of bytes to allocate (e.g. 1024, 1g, 64K) - press any key or CTRL+C to free the memory and exit the program
-o file to output to - ???
-s run silently (requires -b and -o) - profit
-w disable warnings ("i know what i'm doing!")
```
## how to compile ## how to compile
- get a c compiler (i use gcc or clang) - get a c compiler (i use gcc)
- `gcc -o ./allocatememory -O2 ./main.c` - `gcc -o ./allocatememory.exe ./main.c`
- ??? - ???
- profit - profit

225
main.c
View file

@ -1,211 +1,48 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#define BYTES_GIVEN 1 int main() {
#define OUTPUT_FILE 2
#define SILENT 4
#define BYPASS_WARN 8
#define KiB (unsigned long long int) 0x400 unsigned long long int size = 0;
#define MiB (unsigned long long int) 0x100000 unsigned int gib = 0;
#define GiB (unsigned long long int) 0x40000000
#define TiB (unsigned long long int) 0x10000000000 printf("please enter the number of gibibytes (GiB) you would like to allocate (1 GiB = 1073741824 bytes):\n> ");
unsigned int digit = 0;
while (1) {
unsigned char input = getchar();
if (input == '\n') break;
if (input < '0' || input > '9') continue;
#define LOADS TiB * 9999 if (digit > 0) gib = gib * 10;
void print_help(); gib = gib + (unsigned int) input - 48;
unsigned char* get_shorthand(unsigned long long int size); digit++;
void adjust_by_denomination(unsigned long long int* size, char denomination); }
unsigned long long int* allocate_heap(unsigned long long int size, char silent);
void save_heap(unsigned long long int* heap, unsigned long long int size, char* filename, char silent);
int main(int argc, char* argv[]) { size = (unsigned long long int) gib * 1024 * 1024 * 1024;
unsigned char flags = 0; printf("you are about to allocate %d GiB (%llu bytes) of heap memory. are you sure? (y/n)\n> ", gib, size);
unsigned long long int size = 0;
unsigned char* filename = NULL;
unsigned char denominator = 0;
int arg; unsigned char input = getchar();
while ((arg = getopt(argc, argv, "hb:o:sw")) != -1) { if (input != 'y') return 0;
switch (arg) { while (getchar() != '\n');
case 'h':
print_help();
exit(0);
case 'b':
size = strtoull(optarg, NULL, 10);
if (errno == EINVAL) {
fprintf(stderr, "argument -b used with invalid value '%s'!\n", optarg);
exit(0);
}
if (errno == ERANGE) {
fprintf(stderr, "byte argument ''%s' out of range!\n", optarg);
exit(0);
}
denominator = optarg[strlen(optarg) - 1];
flags |= BYTES_GIVEN;
break;
case 'o':
filename = optarg;
flags |= OUTPUT_FILE;
break;
case 's':
if (size == 0 || filename == NULL) {
fprintf(stderr, "cannot run silently without -b and -o set!\n");
print_help();
}
flags |= SILENT;
break;
case 'w':
flags |= BYPASS_WARN;
break;
case '?':
if (optopt == 'b' || optopt == 'o')
fprintf(stderr, "argument -%c requires an argument!\n", optopt);
else if (isprint(optopt))
fprintf(stderr, "unknown argument '-%c'.\n", optopt);
else
fprintf(stderr, "unknown argument character '\\x%x'.\n", optopt);
exit(1);
default:
exit(1);
}
}
if (!(flags & BYTES_GIVEN)) { printf("please wait");
fprintf(stderr, "argument -b is required!\n", optopt); unsigned long long int* wtf = (unsigned long long int*) malloc(size);
print_help();
exit(1);
}
adjust_by_denomination(&size, denominator); for (unsigned long long int i = 0; i < size / sizeof(long long int); i++) {
wtf[i] = 0x80085;
if (i > 0 && i % (1024 * 1024 * 1024 / sizeof(long long int)) == 0) printf(".");
}
printf("\n");
// even if the user doesn't specify a denomination, it still would be nice to display a truncated amount if available. printf("%d GiB (%llu bytes) of heap memory has been allocated. you are insane.\n", gib, size);
unsigned char* shorthand = get_shorthand(size); printf("press ENTER to release this memory, or CTRL+C to exit the program.\n");
if (!(flags & SILENT) && !(flags & BYPASS_WARN)) {
if (shorthand) {
printf("you are about to allocate %s (%llu bytes) of heap memory. are you sure? (y/N)\n> ", shorthand, size);
} else {
printf("you are about to allocate %llu byte%c of heap memory. are you sure? (y/N)\n> ", size, size == 1 ? 0 : 's');
}
unsigned char input = getchar(); getchar();
if (input != 'y') exit(0);
while (getchar() != '\n');
}
unsigned long long int* heap = allocate_heap(size, flags & SILENT); free(wtf);
if (filename != NULL) save_heap(heap, size, filename, flags & SILENT);
if (!(flags & SILENT)) { return 0;
if (shorthand) {
printf("%s (%llu bytes) of heap memory has been allocated. you are insane.\n", shorthand, size);
} else {
printf("%llu byte%c of heap memory ha%s been allocated. you are insane.\n", size, size == 1 ? 0 : 's', size == 1 ? "s" : "ve");
}
free(shorthand);
printf("press ENTER to release this memory, or CTRL+C to exit the program.\n");
getchar();
free(heap);
exit(0);
}
free(heap);
return 0;
} }
void print_help() {
printf("usage: allocatememory -b <bytes> [-o <output file>] [-s]\n\n");
printf("OPTIONS\n");
printf(" -h\tdisplays help\n");
printf(" -b\tnumber of bytes to allocate (e.g. 1024, 1g, 64K)\n");
printf(" -o\tfile to output to\n");
printf(" -s\trun silently (requires -b and -o)\n");
printf(" -w\tdisable warnings (\"i know what i'm doing!\")\n");
exit(0);
}
unsigned char* get_shorthand(unsigned long long int size) {
if (size < KiB) return 0;
if (size > LOADS) {
return ">9999 TiB";
}
unsigned char* buffer = malloc(sizeof(char) * 12);
if (size >= TiB) {
snprintf(buffer, 12, "%.2f TiB", (float) size / TiB);
return buffer;
}
if (size >= GiB) {
snprintf(buffer, 12, "%.2f GiB", (float) size / GiB);
return buffer;
}
if (size >= MiB) {
snprintf(buffer, 12, "%.2f MiB", (float) size / MiB);
return buffer;
}
if (size >= KiB) {
snprintf(buffer, 12, "%.2f KiB", (float) size / KiB);
return buffer;
}
return 0;
}
void adjust_by_denomination(unsigned long long int* size, char denomination) {
if (denomination >= 'a' && denomination <= 'z') denomination -= 32;
switch (denomination) {
case 'K':
*size *= KiB;
return;
case 'M':
*size *= MiB;
return;
case 'G':
*size *= GiB;
return;
case 'T':
*size *= TiB;
return;
}
}
unsigned long long int* allocate_heap(unsigned long long int size, char silent) {
if (!silent) {
printf("please wait.");
fflush(stdout);
}
unsigned long long int* heap = (unsigned long long int*) malloc(size);
for (unsigned long long int i = 0; i < size / sizeof(long long int); i++) {
heap[i] = i;
if (!silent && i > 0 && i % (1024 * 1024 * 1024 / sizeof(long long int)) == 0) {
printf(".");
fflush(stdout);
}
}
if (!silent) printf("\n");
return heap;
}
void save_heap(unsigned long long int* heap, unsigned long long int size, char* filename, char silent) {
FILE* file = fopen(filename, "wb");
if (file == NULL) {
printf("failed to open %s!", filename);
exit(1);
}
fwrite(heap, sizeof(char), size, file);
fputs("\n", file);
fclose(file);
}