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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

char* make_divider(char divider_char, int num_repetitions) {
    // char divider[100];  // BAD!!!!  DANGER!!!
    //                     // PROBLEM #1:  We don't know how big the buffer may be.
    //                     // PROBLEM #2:  We can't return an address of a local variable
    //                                     in this function.  Along the same lines, you
    //                                     cannot return an array created in this function
    //                                     in this way.

    // TODO:  Create a “buffer” (area of memory) to store our result string.

    // Allocate buffer for our divider string.  We need one extra byte for '\n' (newline)
    // and one more byte for the '\0' (null terminator).
    char* divider = malloc( (num_repetitions + 2) * sizeof(*divider) );
    //                      └────────┬──────────┘   └───────┬──────┘
    //                         number of chars    number of bytes to store one char
    //
    // malloc(…) returns the address of a newly allocated buffer on the heap.

    // for(int i = 0; i < (num_repetitions + 1); i++) {   // BUG!!!!
    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");

    // TODO:  Free the heap memory.  (⇒ Give it back to the system.)
    return EXIT_SUCCESS;
}


/*

$ valgrind ./make_divider__no_free__memory_leak
==8148== Memcheck, a memory error detector
==8148== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8148== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==8148== Command: ./make_divider__no_free__memory_leak
==8148==
The party don't start until I arrive.
--------------------------------------------------------------------------------
I'm here.  Let's party.
==8148==
==8148== HEAP SUMMARY:
==8148==     in use at exit: 82 bytes in 1 blocks
==8148==   total heap usage: 1 allocs, 0 frees, 82 bytes allocated
==8148==
==8148== 82 bytes in 1 blocks are definitely lost in loss record 1 of 1
==8148==    at 0x4C29F73: malloc (vg_replace_malloc.c:309)
==8148==    by 0x4005F4: make_divider (make_divider__no_free__memory_leak.c:18)
==8148==    by 0x400667: main (make_divider__no_free__memory_leak.c:35)
==8148==
==8148== LEAK SUMMARY:
==8148==    definitely lost: 82 bytes in 1 blocks
==8148==    indirectly lost: 0 bytes in 0 blocks
==8148==      possibly lost: 0 bytes in 0 blocks
==8148==    still reachable: 0 bytes in 0 blocks
==8148==         suppressed: 0 bytes in 0 blocks
==8148==
==8148== For lists of detected and suppressed errors, rerun with: -s
==8148== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

$

*/
/* vim: set tabstop=4 shiftwidth=4 fileencoding=utf-8 noexpandtab: */

© Copyright 2021 Alexander J. Quinn         This content is protected and may not be shared, uploaded, or distributed.