1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | #include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
char* make_divider(char divider_char, int num_repetitions) {
// Allocate buffer for our divider string, a '\n', and a '\0'.
// char* divider = malloc( (num_repetitions + 2) * sizeof(*divider) ); // GOOD
char* divider = malloc( (num_repetitions + 2) * sizeof(char) );
// └─┬┘
// BAD!!!!
//
// sizeof(«TYPE») → # of bytes to store one object of type «TYPE».
// sizeof(«EXPR») → # of bytes to store one object of the same type as «EXPR»
//
// Do not use sizeof(«TYPE») with a type.
// Always use sizeof(«EXPR») with an expression of that type.
//
// WHY?
//
// If we change the code and forget to modify the type in the sizeof(…) we may end up
// with a buffer overflow, which can cause crashes or security vulnerabilities.
wchar* divider = malloc( (num_repetitions + 2) * sizeof(char) );
// ▲
// ASSUME: sizeof(wchar) == 4 and sizeof(char) is 1.
for(int i = 0; i < num_repetitions; i++) {
divider[i] = divider_char;
}
divider[num_repetitions] = '\n'; // after the last divider character
divider[num_repetitions + 1] = '\0'; // after the '\n'.
return divider;
}
int main(int argc, char* argv[]) {
char* divider = make_divider('-', 80);
printf("The party don't start until I arrive.\n");
printf("%s", divider);
printf("I'm here. Let's party.\n");
// Free the heap memory. (⇒ Give it back to the system.)
free(divider);
return EXIT_SUCCESS;
}
|
© Copyright 2021 Alexander J. Quinn This content is protected and may not be shared, uploaded, or distributed.