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.