3

I'm hoping to avoid any memory leaks in a program that needs to read a command-line argument that is a path to a parameter file to be read. If I compile the following program and check the executable with valgrind, I still get returned a leak summary that has possibly lost: 72 bytes in 3 blocks. How do I avoid memory leaks in the following set up?

Many thanks in advance for the help!

// main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "constant.h"

void set_up_parameters(parameters *params, int argc, char **argv) {
    char *input_file_name_ptr;
    input_file_name_ptr = calloc((INPUT_CHAR_LEN + 1), sizeof(char));
    if (input_file_name_ptr == NULL) {
        printf("Cannot allocate input_file_name_ptr\n");
        exit(1);
    }
    params->input_file_name = input_file_name_ptr;
}

int main(int argc, char *argv[]) {
    parameters *params_ptr;
    params_ptr = NULL;
    params_ptr = calloc(1, sizeof(parameters));
    if (params_ptr == NULL) {
        printf("Cannot allocate parameters\n");
        exit(1);
    }

    set_up_parameters(params_ptr, argc, argv);

    free(params_ptr->input_file_name);
    free(params_ptr);
    return 0;
}

where my file constant.h is the following:

#define INPUT_CHAR_LEN 100

typedef struct {
    char *input_file_name;
    int n_params;
} parameters;

Update

Many thanks for all the responses. I adjusted to include the line free(params); in set_up_parameters() just before exit(1) as suggested. I then compiled using the following:

gcc -c -O3 -ggdb3 main.c
gcc main.o -o check.exe

I obtained output from valgrind (using the command valgrind --leak-check=full --show-leak-kinds=all --verbose --track-origins=yes --log-file=valgrind.log ./check.exe) which was the following:

==39172== Memcheck, a memory error detector
==39172== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==39172== Using Valgrind-3.15.0-608cb11914-20190413 and LibVEX; rerun with -h for copyright info
==39172== Command: ./check.exe
==39172== Parent PID: 33579
==39172== 
--39172-- 
--39172-- Valgrind options:
--39172--    --leak-check=full
--39172--    --show-leak-kinds=all
--39172--    --verbose
--39172--    --track-origins=yes
--39172--    --log-file=valgrind.log
--39172-- Output from sysctl({CTL_KERN,KERN_VERSION}):
--39172--   Darwin Kernel Version 17.7.0: Fri Oct  4 23:08:59 PDT 2019; root:xnu-4570.71.57~1/RELEASE_X86_64
--39172-- Arch and hwcaps: AMD64, LittleEndian, amd64-cx16-lzcnt-rdtscp-sse3-ssse3-avx-avx2-bmi-f16c-rdrand
--39172-- Page sizes: currently 4096, max supported 4096
--39172-- Valgrind library directory: /usr/local/Cellar/valgrind/3.15.0/lib/valgrind
--39172-- ./check.exe (rx at 0x100000000, rw at 0x100001000)
--39172--    reading syms   from primary file (3 12)
--39172--    dSYM= ./check.exe.dSYM/Contents/Resources/DWARF/check.exe
--39172--    reading dwarf3 from dsyms file
--39172-- /usr/lib/dyld (rx at 0x100003000, rw at 0x10004e000)
--39172--    reading syms   from primary file (5 1487)
--39172-- Scheduler: using generic scheduler lock implementation.
--39172-- Reading suppressions file: /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp
.... (removed lines due to links to personal dirs)
==39172== 
==39172== TO CONTROL THIS PROCESS USING vgdb (which you probably
==39172== don't want to do, unless you know exactly what you're doing,
==39172== or are doing some strange experiment):
==39172==   /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/../../bin/vgdb --pid=39172 ...command...
==39172== 
==39172== TO DEBUG THIS PROCESS USING GDB: start GDB like this
==39172==   /path/to/gdb ./check.exe
==39172== and then give GDB the following command
==39172==   target remote | /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/../../bin/vgdb --pid=39172
==39172== --pid is optional if only one valgrind process is running
==39172== 
--39172-- REDIR: 0x100030ac0 (dyld:strcmp) redirected to 0x258057de2 (???)
--39172-- REDIR: 0x10002abac (dyld:arc4random) redirected to 0x258057e80 (???)
--39172-- REDIR: 0x10002aa60 (dyld:strlen) redirected to 0x258057db1 (???)
--39172-- REDIR: 0x10002a9c0 (dyld:strcpy) redirected to 0x258057dfe (???)
--39172-- REDIR: 0x10002e0e6 (dyld:strcat) redirected to 0x258057dc2 (???)
--39172-- REDIR: 0x10002e124 (dyld:strlcat) redirected to 0x258057e1b (???)
--39172-- /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_core-amd64-darwin.so (rx at 0x1000a1000, rw at 0x1000a7000)
--39172--    reading syms   from primary file (3 93)
--39172--    dSYM= /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_core-amd64-darwin.so.dSYM/Contents/Resources/DWARF/vgpreload_core-amd64-darwin.so
--39172-- /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so (rx at 0x1000ab000, rw at 0x1000b3000)
--39172--    reading syms   from primary file (72 102)
--39172--    dSYM= /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so.dSYM/Contents/Resources/DWARF/vgpreload_memcheck-amd64-darwin.so
--39172-- /usr/lib/libSystem.B.dylib (rx at 0x1000b9000, rw at 0x1000bb000)
--39172--    reading syms   from primary file (31 5)
--39172-- /usr/lib/system/libcache.dylib (rx at 0x1000c1000, rw at 0x1000c6000)
--39172--    reading syms   from primary file (32 29)
--39172-- /usr/lib/system/libcommonCrypto.dylib (rx at 0x1000cb000, rw at 0x1000d6000)
--39172--    reading syms   from primary file (221 169)
--39172-- /usr/lib/system/libcompiler_rt.dylib (rx at 0x1000e3000, rw at 0x1000eb000)
--39172--    reading syms   from primary file (510 8)
--39172-- /usr/lib/system/libcopyfile.dylib (rx at 0x1000f8000, rw at 0x100102000)
--39172--    reading syms   from primary file (13 35)
--39172-- /usr/lib/system/libcorecrypto.dylib (rx at 0x100108000, rw at 0x10018e000)
--39172--    reading syms   from primary file (512 677)
--39172-- /usr/lib/system/libdispatch.dylib (rx at 0x1001aa000, rw at 0x1001e4000)
--39172--    reading syms   from primary file (271 945)
--39172-- /usr/lib/system/libdyld.dylib (rx at 0x10021e000, rw at 0x10023c000)
--39172--    reading syms   from primary file (97 992)
--39172-- /usr/lib/system/libkeymgr.dylib (rx at 0x100256000, rw at 0x100257000)
--39172--    reading syms   from primary file (12 3)
--39172-- /usr/lib/system/libmacho.dylib (rx at 0x100262000, rw at 0x100267000)
--39172--    reading syms   from primary file (105 1)
--39172-- /usr/lib/system/libquarantine.dylib (rx at 0x10026d000, rw at 0x100270000)
--39172--    reading syms   from primary file (67 6)
--39172-- /usr/lib/system/libremovefile.dylib (rx at 0x100275000, rw at 0x100277000)
--39172--    reading syms   from primary file (15 4)
--39172-- /usr/lib/system/libsystem_asl.dylib (rx at 0x10027c000, rw at 0x100294000)
--39172--    reading syms   from primary file (222 225)
--39172-- /usr/lib/system/libsystem_blocks.dylib (rx at 0x1002a1000, rw at 0x1002a2000)
--39172--    reading syms   from primary file (21 6)
--39172-- /usr/lib/system/libsystem_c.dylib (rx at 0x1002a6000, rw at 0x100330000)
--39172--    reading syms   from primary file (1342 806)
--39172-- /usr/lib/system/libsystem_configuration.dylib (rx at 0x100358000, rw at 0x10035c000)
--39172--    reading syms   from primary file (38 66)
--39172-- /usr/lib/system/libsystem_coreservices.dylib (rx at 0x100362000, rw at 0x100366000)
--39172--    reading syms   from primary file (14 37)
--39172-- /usr/lib/system/libsystem_darwin.dylib (rx at 0x10036b000, rw at 0x10036d000)
--39172--    reading syms   from primary file (12 105)
--39172-- /usr/lib/system/libsystem_dnssd.dylib (rx at 0x100372000, rw at 0x100379000)
--39172--    reading syms   from primary file (49 24)
--39172-- /usr/lib/system/libsystem_info.dylib (rx at 0x10037f000, rw at 0x1003c9000)
--39172--    reading syms   from primary file (525 650)
--39172-- /usr/lib/system/libsystem_m.dylib (rx at 0x1003e0000, rw at 0x10042c000)
--39172--    reading syms   from primary file (805 1)
--39172-- /usr/lib/system/libsystem_malloc.dylib (rx at 0x10043a000, rw at 0x10045a000)
--39172--    reading syms   from primary file (127 264)
--39172-- /usr/lib/system/libsystem_network.dylib (rx at 0x100466000, rw at 0x100597000)
--39172--    reading syms   from primary file (1126 1216)
--39172-- /usr/lib/system/libsystem_networkextension.dylib (rx at 0x1005d7000, rw at 0x1005e2000)
--39172--    reading syms   from primary file (98 229)
--39172-- /usr/lib/system/libsystem_notify.dylib (rx at 0x1005ee000, rw at 0x1005f8000)
--39172--    reading syms   from primary file (113 54)
--39172-- /usr/lib/system/libsystem_sandbox.dylib (rx at 0x1005ff000, rw at 0x100603000)
--39172--    reading syms   from primary file (93 8)
--39172-- /usr/lib/system/libsystem_secinit.dylib (rx at 0x100609000, rw at 0x10060b000)
--39172--    reading syms   from primary file (1 7)
--39172-- /usr/lib/system/libsystem_kernel.dylib (rx at 0x100610000, rw at 0x100637000)
--39172--    reading syms   from primary file (1282 100)
--39172-- /usr/lib/system/libsystem_platform.dylib (rx at 0x100650000, rw at 0x100658000)
--39172--    reading syms   from primary file (157 101)
--39172-- /usr/lib/system/libsystem_pthread.dylib (rx at 0x100660000, rw at 0x10066c000)
--39172--    reading syms   from primary file (178 77)
--39172-- /usr/lib/system/libsystem_symptoms.dylib (rx at 0x100678000, rw at 0x100680000)
--39172--    reading syms   from primary file (10 93)
--39172-- /usr/lib/system/libsystem_trace.dylib (rx at 0x100686000, rw at 0x10069a000)
--39172--    reading syms   from primary file (114 245)
--39172-- /usr/lib/system/libunwind.dylib (rx at 0x1006a8000, rw at 0x1006ae000)
--39172--    reading syms   from primary file (102 52)
--39172-- /usr/lib/system/libxpc.dylib (rx at 0x1006b5000, rw at 0x1006e3000)
--39172--    reading syms   from primary file (567 915)
--39172-- /usr/lib/closure/libclosured.dylib (rx at 0x100705000, rw at 0x100739000)
--39172--    reading syms   from primary file (1 966)
--39172-- /usr/lib/libobjc.A.dylib (rx at 0x100754000, rw at 0x100b43000)
--39172--    reading syms   from primary file (369 902)
--39172-- /usr/lib/libc++abi.dylib (rx at 0x100cf3000, rw at 0x100d18000)
--39172--    reading syms   from primary file (369 212)
--39172-- /usr/lib/libc++.1.dylib (rx at 0x100d27000, rw at 0x100d7e000)
--39172--    reading syms   from primary file (2023 1681)
--39172-- REDIR: 0x100650ac0 (libsystem_platform.dylib:_platform_memchr$VARIANT$Haswell) redirected to 0x1000adbc5 (_platform_memchr$VARIANT$Haswell)
--39172-- REDIR: 0x100650ba0 (libsystem_platform.dylib:_platform_memcmp) redirected to 0x1000ae2b2 (_platform_memcmp)
--39172-- REDIR: 0x1006510e0 (libsystem_platform.dylib:_platform_strncmp) redirected to 0x1000adaca (_platform_strncmp)
--39172-- REDIR: 0x1002a7220 (libsystem_c.dylib:strlen) redirected to 0x1000ad75b (strlen)
--39172-- REDIR: 0x1006516a0 (libsystem_platform.dylib:_platform_strcmp) redirected to 0x1000adb44 (_platform_strcmp)
--39172-- REDIR: 0x10043e5f4 (libsystem_malloc.dylib:calloc) redirected to 0x1000ac62f (calloc)
--39172-- REDIR: 0x10043dca0 (libsystem_malloc.dylib:malloc_default_zone) redirected to 0x1000ad36c (malloc_default_zone)
--39172-- REDIR: 0x10043c1da (libsystem_malloc.dylib:malloc_zone_malloc) redirected to 0x1000ac27b (malloc_zone_malloc)
--39172-- REDIR: 0x10043dca9 (libsystem_malloc.dylib:malloc_zone_calloc) redirected to 0x1000ac81d (malloc_zone_calloc)
--39172-- REDIR: 0x10043b5a7 (libsystem_malloc.dylib:malloc) redirected to 0x1000ac010 (malloc)
--39172-- REDIR: 0x10043dd71 (libsystem_malloc.dylib:malloc_zone_from_ptr) redirected to 0x1000ad3ad (malloc_zone_from_ptr)
--39172-- REDIR: 0x10043d69d (libsystem_malloc.dylib:free) redirected to 0x1000ac3f1 (free)
--39172-- REDIR: 0x10043e7a7 (libsystem_malloc.dylib:realloc) redirected to 0x1000ac9b1 (realloc)
--39172-- REDIR: 0x1006512c0 (libsystem_platform.dylib:_platform_strchr$VARIANT$Haswell) redirected to 0x1000ad61f (_platform_strchr$VARIANT$Haswell)
==39172== 
==39172== HEAP SUMMARY:
==39172==     in use at exit: 18,306 bytes in 163 blocks
==39172==   total heap usage: 184 allocs, 21 frees, 26,754 bytes allocated
==39172== 
==39172== Searching for pointers to 163 not-freed blocks
==39172== Checked 10,808,216 bytes
==39172== 
==39172== 24 bytes in 1 blocks are still reachable in loss record 3 of 42
==39172==    at 0x1000AC2FE: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x100757928: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007578FA: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007563CB: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007560DA: sel_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007559AD: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==39172==    by 0x10022171D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==39172==    by 0x100755075: _objc_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1001ABB34: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==39172== 
==39172== 32 bytes in 1 blocks are still reachable in loss record 8 of 42
==39172==    at 0x1000AC2FE: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x100757A80: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757A50: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757950: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007578FA: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007563CB: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007560DA: sel_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007559AD: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==39172==    by 0x10022171D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==39172== 
==39172== 32 bytes in 1 blocks are still reachable in loss record 9 of 42
==39172==    at 0x1000AC2FE: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x100757AA1: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757A50: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757950: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007578FA: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007563CB: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007560DA: sel_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007559AD: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==39172==    by 0x10022171D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==39172== 
==39172== 32 bytes in 1 blocks are still reachable in loss record 10 of 42
==39172==    at 0x1000AC086: malloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x100757B65: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757A50: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757950: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007578FA: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007563CB: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007560DA: sel_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007559AD: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==39172==    by 0x10022171D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==39172== 
==39172== 32 bytes in 1 blocks are still reachable in loss record 11 of 42
==39172==    at 0x1000AC086: malloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x1007579B6: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007578FA: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007563CB: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007560DA: sel_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007559AD: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==39172==    by 0x10022171D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==39172==    by 0x100755075: _objc_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1001ABB34: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==39172== 
==39172== 48 bytes in 1 blocks are still reachable in loss record 15 of 42
==39172==    at 0x1000AC8AD: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x100757F18: _NXHashRehashToCapacity (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757E96: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757B8F: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757A50: NXCreateHashTable (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100757950: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007578FA: NXCreateMapTableFromZone (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007563CB: __sel_registerName(char const*, int, int) (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007560DA: sel_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007559AD: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172== 
==39172== 72 bytes in 3 blocks are possibly lost in loss record 26 of 42
==39172==    at 0x1000AC6EA: calloc (in /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==39172==    by 0x1007557E2: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1007687DA: objc_object::sidetable_retainCount() (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x100007C64: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*), bool, bool) (in /usr/lib/dyld)
==39172==    by 0x100007E39: dyld::registerObjCNotifiers(void (*)(unsigned int, char const* const*, mach_header const* const*), void (*)(char const*, mach_header const*), void (*)(char const*, mach_header const*)) (in /usr/lib/dyld)
==39172==    by 0x10022171D: _dyld_objc_notify_register (in /usr/lib/system/libdyld.dylib)
==39172==    by 0x100755075: _objc_init (in /usr/lib/libobjc.A.dylib)
==39172==    by 0x1001ABB34: _os_object_init (in /usr/lib/system/libdispatch.dylib)
==39172==    by 0x1001ABB1B: libdispatch_init (in /usr/lib/system/libdispatch.dylib)
==39172==    by 0x1000BA9C2: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==39172==    by 0x100019AC5: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==39172==    by 0x100019CF5: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==39172== 
==39172== LEAK SUMMARY:
==39172==    definitely lost: 0 bytes in 0 blocks
==39172==    indirectly lost: 0 bytes in 0 blocks
==39172==      possibly lost: 72 bytes in 3 blocks
==39172==    still reachable: 200 bytes in 6 blocks
==39172==         suppressed: 18,034 bytes in 154 blocks
==39172== 
==39172== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 12)
--39172-- 
--39172-- used_suppression:      5 OSX1013:19-Leak /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:924 suppressed: 8,792 bytes in 5 blocks
--39172-- used_suppression:      7 OSX1013:17-Leak /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:906 suppressed: 3,744 bytes in 59 blocks
--39172-- used_suppression:      3 OSX1013:16-Leak /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:897 suppressed: 3,200 bytes in 50 blocks
--39172-- used_suppression:     16 OSX1013:10-Leak /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:839 suppressed: 2,178 bytes in 36 blocks
--39172-- used_suppression:      4 OSX1013:18-Leak /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:915 suppressed: 120 bytes in 4 blocks
--39172-- used_suppression:      1 OSX1013:dyld-5 /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:1283
--39172-- used_suppression:      2 OSX1013:dyld-4 /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:1275
--39172-- used_suppression:      1 OSX1013:dyld-3 /usr/local/Cellar/valgrind/3.15.0/lib/valgrind/default.supp:1267
==39172== 
==39172== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 12)
p-robot
  • 4,652
  • 2
  • 29
  • 38
  • 2
    The valgrind messages may not be related to your `calloc()`s at all. It might be something glibc internal (it almost certainly is: valgrind reports 3 blocks, while you allocate only 2). To analyze further, compile with `-ggdb`, re-run with valgrind and show the output here. – Ctx Mar 11 '20 at 15:25
  • @Ctx That would be easy to check by commenting out the callocs (and any access to that data, but I think there isn't any)... – Peter - Reinstate Monica Mar 11 '20 at 15:26
  • 2
    valgrind should tell you where the blocks were allocated (you may need to pass additional arguments like `--leak-check=full` to see them) – Kevin Mar 11 '20 at 15:27
  • 1
    You have *kind* of leak when calling `exit(1)` in `set_up_parameters`. Do a cleanup before it or ignore. – Eugene Sh. Mar 11 '20 at 15:30
  • 1
    @Peter-ReinstateMonica That's another possibility, right. I will forward it to the OP: Do as Peter suggests. – Ctx Mar 11 '20 at 15:30
  • Make sure you compile and link with appropriate `-g` options so Valgrind can give good stack trace information (line numbers, etc). Show the Valgrind report summary. Make sure you got as much information as possible from Valgrind. It normally tells you fairly precisely where stuff was allocated. On the face of it, you allocate two blocks of memory, but Valgrind says that three are possibly lost. It sounds like the startup code (before your `main()` is called) is doing memory allocation that is not suppressed. You may need to get Valgrind to generate suppression information and use it. – Jonathan Leffler Mar 11 '20 at 15:49

2 Answers2

4

Strictly speaking, this is a leak:

if(input_file_name_ptr == NULL){
        printf("Cannot allocate input_file_name_ptr\n");
        exit(1);
}

Should be written as

if(input_file_name_ptr == NULL){
        free(params);
        printf("Cannot allocate input_file_name_ptr\n");
        exit(1);
}

Might be enough to trigger the tool warning.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 1
    If you are feeling fancy, you could also register a custom clean-up function with `atexit()`. Such as: `static parameters *params_ptr;` .. `void cleanup (void) { if(params_ptr) free(params_ptr->input_file_name); free(params_ptr); }` ...`atexit(cleanup)`. Though this relies on static initialization and calloc both setting the memory to NULL. – Lundin Mar 11 '20 at 15:41
  • Good point. Many thanks! I've adjusted in the edited version. So would it be reasonable to ignore these `possibly lost` flags that I get from `valgrind`? – p-robot Mar 11 '20 at 23:45
0

Possibly lost means your program is leaking memory, unless you're doing unusual things with pointers that could cause them to point into the middle of an allocated block. But valgrind can't tell whether it is a programming error or you are being clever doing this deliberately. That is why it warns you. The beow code will fix the issue:

/ main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "constant.h"

void set_up_parameters( parameters *params, int argc, char **argv )
{
    char *input_file_name_ptr;
    input_file_name_ptr = calloc((INPUT_CHAR_LEN + 1), sizeof(char));
    if(input_file_name_ptr == NULL){

        /* before exiting the process, we should free memory allocated for params */
        free(params);
        printf("Cannot allocate input_file_name_ptr\n");
        exit(1);
    }
    params->input_file_name = input_file_name_ptr;
}


int main(int argc, char *argv[])
{
    parameters *params_ptr;
    params_ptr = NULL;
    params_ptr = calloc(1, sizeof(parameters));
    if(params_ptr == NULL){
        printf("Cannot allocate parameters\n");
        exit(1);
    }

    set_up_parameters( params_ptr, argc, argv);

    free(params_ptr->input_file_name);
    free(params_ptr);
    return 0;
}
Vinie
  • 101
  • 2
  • 9
  • 1
    I find it generally not helpful to just fix the OP code without at least highlighting the changes. Ideally, I'm always looking for a prosa explanation of the changes. – cmaster - reinstate monica Mar 11 '20 at 16:12
  • The above code frees the `parameters` structure before exiting in case of memory allocation failure, which is unlikely to be the *issue* the OP is experiencing. – chqrlie Mar 11 '20 at 17:15