How do you test Node C++ add-ons with Valgrind? - node.js

Upon running valgrind node, Node seems to abort with a somewhat cryptic syscall-related error.
I'm on macOS Sierra, Node v8.2.1.
$ valgrind `which node` test-pass.js
==17115== Memcheck, a memory error detector
==17115== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==17115== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==17115== Command: /Users/junon/n/bin/node test-pass.js
==17115==
==17115== Syscall param msg->desc.port.name points to uninitialised byte(s)
==17115== at 0x10352B34A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x10352A796: mach_msg (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x103524485: task_set_special_port (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x1036C010E: _os_trace_create_debug_control_port (in /usr/lib/system/libsystem_trace.dylib)
==17115== by 0x1036C0458: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib)
==17115== by 0x1029B29DF: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==17115== by 0x1021ECA1A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==17115== by 0x1021ECC1D: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==17115== by 0x1021E84A9: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==17115== by 0x1021E8440: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==17115== by 0x1021E7523: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==17115== by 0x1021E75B8: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==17115== Address 0x7fff5fbfda8c is on thread 1's stack
==17115== in frame #2, created by task_set_special_port (???:)
==17115==
Assertion failed: (process_title.len + 1 == size), function uv_setup_args, file ../deps/uv/src/unix/proctitle.c, line 58.
==17115==
==17115== Process terminating with default action of signal 6 (SIGABRT)
==17115== at 0x103532D72: __pthread_sigmask (in /usr/lib/system/libsystem_kernel.dylib)
==17115== by 0x1034404A8: __abort (in /usr/lib/system/libsystem_c.dylib)
==17115== by 0x10344042E: abort (in /usr/lib/system/libsystem_c.dylib)
==17115== by 0x103407892: __assert_rtn (in /usr/lib/system/libsystem_c.dylib)
==17115== by 0x100BEC7B6: uv_setup_args (in /Users/junon/n/bin/node)
==17115== by 0x100A7EC9F: node::Start(int, char**) (in /Users/junon/n/bin/node)
==17115== by 0x100000E33: (below main) (in /Users/junon/n/bin/node)
==17115==
==17115== HEAP SUMMARY:
==17115== in use at exit: 71,518 bytes in 369 blocks
==17115== total heap usage: 469 allocs, 100 frees, 108,584 bytes allocated
==17115==
==17115== LEAK SUMMARY:
==17115== definitely lost: 0 bytes in 0 blocks
==17115== indirectly lost: 0 bytes in 0 blocks
==17115== possibly lost: 7,272 bytes in 115 blocks
==17115== still reachable: 10,270 bytes in 98 blocks
==17115== suppressed: 53,976 bytes in 156 blocks
==17115== Rerun with --leak-check=full to see details of leaked memory
==17115==
==17115== For counts of detected and suppressed errors, rerun with: -v
==17115== Use --track-origins=yes to see where uninitialised values come from
==17115== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 1 from 1)
[1] 17115 abort valgrind `which node` test-pass.js
How are you supposed to check for memory leaks within C++ add-ons for Node.js? I see mentions of using node_g from around 2010, but that executable appears to be missing from my installation.

Related

why not getting SIGSEGV when overflowing .data section [duplicate]

I'm experimenting with assembly language and wrote a program which prints 2 hardcoded bytes into stdout. Here it is:
section .text
global _start
_start:
mov eax, 0x0A31
mov [val], eax
mov eax, 4
mov ebx, 1
mov ecx, val
mov edx, 2
int 0x80
mov eax, 1
int 0x80
segment .bss
val resb 1; <------ Here
Note that I reserved only 1 byte inside the bss segment, but actually put 2 bytes (charcode for 1 and newline symbol) into the memory location. And the program worked fine. It printed 1 character and then newline.
But I expected segmentation fault. Why isn't it occured. We reserved only 1 byte, but put 2.
x86, like most other modern architectures, uses paging / virtual memory for memory protection. On x86 (again like many other architectures), the granularity is 4kiB.
A 4-byte store to val won't fault unless the linker happens to place it in the last 3 bytes of a page, and the next page is unmapped.
What actually happens is that you just overwrite whatever is after val. In this case, it's just unused space to the end of the page. If you had other static storage locations in the BSS, you'd step on their values. (Call them "variables" if you want, but the high-level concept of a "variable" doesn't just mean a memory location, a variable can be live in a register and never needs to have an address.)
Besides the wikipedia article linked above, see also:
How does x86 paging work? (internals of the page-table format, and how the OS manages it and the CPU reads it).
What is the state of the art in Memory Protection?
Is it safe to read past the end of a buffer within the same page on x86 and x64?
About the memory layout of programs in Linux
but actually put 2 bytes (charcode for 1 and newline symbol) into the memory location.
mov [val], eax is a 4-byte store. The operand-size is determined by the register. If you wanted to do a 2-byte store, use mov [val], ax.
Fun fact: MASM would warn or error about an operand-size mismatch, because it magically associates sizes with symbol names based on the declaration that reserves space after them. NASM stays out of your way, so if you wrote mov [val], 0x0A31, it would be an error. Neither operand implies a size, so you need mov dword [val], 0x0A31 (or word or byte).
Placing val at the end of a page to get a segfault
The BSS for some reason doesn't start at the beginning of a page in a 32-bit binary, but it is near the start of a page. You're not linking with anything else that would use up most of a page in the BSS. nm bss-no-segfault shows that it's at 0x080490a8, and a 4k page is 0x1000 bytes, so the last byte in the BSS mapping will be 0x08049fff.
It seems that the BSS start address changes when I add an instruction to the .text section, so presumably the linker's choices here are related to packing things into an ELF executable. It doesn't make much sense, because the BSS isn't stored in the file, it's just a base address + length. I'm not going down that rabbit hole; I'm sure there's a reason that making .text slightly larger results in a BSS that starts at the beginning of a page, but IDK what it is.
Anyway, if we construct the BSS so that val is right before the end of a page, we can get a fault:
... same .text
section .bss
dummy: resb 4096 - 0xa8 - 2
val: resb 1
;; could have done this instead of making up constants
;; ALIGN 4096
;; dummy2: resb 4094
;; val2: resb
Then build and run:
$ asm-link -m32 bss-no-segfault.asm
+ yasm -felf32 -Worphan-labels -gdwarf2 bss-no-segfault.asm
+ ld -melf_i386 -o bss-no-segfault bss-no-segfault.o
peter#volta:~/src/SO$ nm bss-no-segfault
080490a7 B __bss_start
080490a8 b dummy
080490a7 B _edata
0804a000 B _end <--------- End of the BSS
08048080 T _start
08049ffe b val <--------- Address of val
gdb ./bss-no-segfault
(gdb) b _start
(gdb) r
(gdb) set disassembly-flavor intel
(gdb) layout reg
(gdb) p &val
$2 = (<data variable, no debug info> *) 0x8049ffe
(gdb) si # and press return to repeat a couple times
mov [var], eax segfaults because it crosses into the unmapped page. mov [var], ax would works (because I put var 2 bytes before the end of the page).
At this point, /proc/<PID>/smaps shows:
... the r-x private mapping for .text
08049000-0804a000 rwxp 00000000 00:15 2885598 /home/peter/src/SO/bss-no-segfault
Size: 4 kB
Rss: 4 kB
Pss: 4 kB
Shared_Clean: 0 kB
Shared_Dirty: 0 kB
Private_Clean: 0 kB
Private_Dirty: 4 kB
Referenced: 4 kB
Anonymous: 4 kB
...
[vvar] and [vdso] pages exported by the kernel for fast gettimeofday / getpid
Key things: rwxp means read/write/execute, and private. Even stopped before the first instruction, somehow it's already "dirty" (i.e. written to). So is the text segment, but that's expected from gdb changing the instruction to int3.
The 08049000-0804a000 (and 4 kB size of the mapping) shows us that the BSS only has 1 page mapped. There's no data segment, just text and BSS.

Running Valgrind: False positives

I am trying to set up Valgrind to detect possible leaks from the native part of an app.
I have managed to build and get it running on my device, but I seem to be getting an error, causing many leaks to be detected whatever I use it on.
Here is the output of me using valgrind on 'ls' (that should come up with 0 leaks):
130|root#hwALE-H:/data/local/Inst/bin # ./valgrind ls
==16610== Memcheck, a memory error detector
==16610== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16610== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==16610== Command: ls
==16610==
WARNING: linker: /data/local/Inst/lib/valgrind/vgpreload_core-arm64-linux.so: unsupported flags DT_FLAGS_1=0x421
WARNING: linker: /data/local/Inst/lib/valgrind/vgpreload_memcheck-arm64-linux.so: unsupported flags DT_FLAGS_1=0x421
==16610== Invalid free() / delete / delete[] / realloc()
==16610== at 0x487D7D4: free (vg_replace_malloc.c:530)
==16610== by 0x40084FB: __dl__ZL12load_libraryilR10LinkedListI8LoadTask18TypeBasedAllocatorI15LinkedListEntryIS0_EEEPKciPK17android_dlextinfo (in /system/bin/linker64)
==16610== by 0x40097AF: __dl__ZL14find_librariesP6soinfoPKPKcmPS0_PNSt3__16vectorIS0_NS6_9allocatorIS0_EEEEmiPK17android_dlextinfo (in /system/bin/linker64)
==16610== by 0x400A883: __dl___linker_init (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== Address 0x4039150 is in a rw- anonymous segment
==16610==
==16610== Invalid free() / delete / delete[] / realloc()
==16610== at 0x487D7D4: free (vg_replace_malloc.c:530)
==16610== by 0x4009A43: __dl__ZL14find_librariesP6soinfoPKPKcmPS0_PNSt3__16vectorIS0_NS6_9allocatorIS0_EEEEmiPK17android_dlextinfo (in /system/bin/linker64)
==16610== by 0x400A883: __dl___linker_init (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== by 0x40029EB: _start (in /system/bin/linker64)
==16610== Address 0x403e010 is in a rw- anonymous segment
==16610==
callgrind_annotate
callgrind_control
cg_annotate
cg_diff
cg_merge
ms_print
valgrind
valgrind-di-server
valgrind-listener
vgdb
==16610==
==16610== HEAP SUMMARY:
==16610== in use at exit: 680 bytes in 12 blocks
==16610== total heap usage: 58 allocs, 48 frees, 72,870 bytes allocated
==16610==
==16610== LEAK SUMMARY:
==16610== definitely lost: 352 bytes in 7 blocks
==16610== indirectly lost: 0 bytes in 0 blocks
==16610== possibly lost: 16 bytes in 1 blocks
==16610== still reachable: 312 bytes in 4 blocks
==16610== suppressed: 0 bytes in 0 blocks
==16610== Rerun with --leak-check=full to see details of leaked memory
==16610==
==16610== For counts of detected and suppressed errors, rerun with: -v
==16610== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Any suggestions to help solve this issue will greatly appreciated!
EDIT: Here is the full logcat output from starting a "HelloJNI" type app, with a 6byte leak from native code. https://pastebin.com/j7TWC5Bu
The trace is hardly usable.

Valgrind errors in c++ threads

I am new to Valgrind. It throws 2 errors during memory check for the following code (http://en.cppreference.com/w/cpp/thread/lock_guard). Not sure how to interpret those errors.
#include <thread>
#include <mutex>
#include <iostream>
int g_i = 0;
std::mutex g_i_mutex; // protects g_i
void safe_increment()
{
std::lock_guard<std::mutex> lock(g_i_mutex);
++g_i;
std::cout << std::this_thread::get_id() << ": " << g_i << '\n';
}
int main()
{
std::cout << __func__ << ": " << g_i << '\n';
std::thread t1(safe_increment);
std::thread t2(safe_increment);
t1.join();
t2.join();
std::cout << __func__ << ": " << g_i << '\n';
}
I compiled this code on Mac using the following command:
clang++ simplethread.cpp -o simplethread -lpthread -std=c++11
The code runs as expected, but I get the following output from Valgrind.
$ valgrind --tool=memcheck ./simplethread
==34831== Memcheck, a memory error detector
==34831== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==34831== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==34831== Command: ./simplethread
==34831==
==34831== Syscall param msg->desc.port.name points to uninitialised byte(s)
==34831== at 0x10045F34A: mach_msg_trap (in /usr/lib/system/libsystem_kernel.dylib)
==34831== by 0x10045E796: mach_msg (in /usr/lib/system/libsystem_kernel.dylib)
==34831== by 0x100458485: task_set_special_port (in /usr/lib/system/libsystem_kernel.dylib)
==34831== by 0x1005F410E: _os_trace_create_debug_control_port (in /usr/lib/system/libsystem_trace.dylib)
==34831== by 0x1005F4458: _libtrace_init (in /usr/lib/system/libsystem_trace.dylib)
==34831== by 0x1000A99DF: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==34831== by 0x10001BA1A: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==34831== by 0x10001BC1D: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==34831== by 0x1000174A9: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==34831== by 0x100017440: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, char const*, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==34831== by 0x100016523: ImageLoader::processInitializers(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&, ImageLoader::UninitedUpwards&) (in /usr/lib/dyld)
==34831== by 0x1000165B8: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==34831== Address 0x10488ed4c is on thread 1's stack
==34831== in frame #2, created by task_set_special_port (???:)
==34831==
main: 0
==34831== Thread 2:
==34831== Invalid read of size 4
==34831== at 0x1005BC899: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC886: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC08C: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== Address 0x18 is not stack'd, malloc'd or (recently) free'd
==34831==
==34831==
==34831== Process terminating with default action of signal 11 (SIGSEGV)
==34831== Access not within mapped region at address 0x18
==34831== at 0x1005BC899: _pthread_body (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC886: _pthread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== by 0x1005BC08C: thread_start (in /usr/lib/system/libsystem_pthread.dylib)
==34831== If you believe this happened as a result of a stack
==34831== overflow in your program's main thread (unlikely but
==34831== possible), you can try to increase the size of the
==34831== main thread stack using the --main-stacksize= flag.
==34831== The main thread stack size used in this run was 8388608.
--34831:0:schedule VG_(sema_down): read returned -4
==34831==
==34831== HEAP SUMMARY:
==34831== in use at exit: 22,494 bytes in 168 blocks
==34831== total heap usage: 184 allocs, 16 frees, 28,638 bytes allocated
==34831==
==34831== LEAK SUMMARY:
==34831== definitely lost: 16 bytes in 1 blocks
==34831== indirectly lost: 56 bytes in 2 blocks
==34831== possibly lost: 72 bytes in 3 blocks
==34831== still reachable: 4,368 bytes in 10 blocks
==34831== suppressed: 17,982 bytes in 152 blocks
==34831== Rerun with --leak-check=full to see details of leaked memory
==34831==
==34831== For counts of detected and suppressed errors, rerun with: -v
==34831== Use --track-origins=yes to see where uninitialised values come from
==34831== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 1 from 1)
Segmentation fault: 11
What does these errors mean ?

Poco Cipher leak

I'm going crazy and after I have googled without answer I'm going to try to write here.
I have Ubuntu 16.04, GCC 5.4.0, Poco 1.7.8-all and OpenSSL 1.1.0e.
and these few lines of code:
int main()
{
const std::string AES_NAME = "aes-128-cbc";
Cipher::Ptr uptrCipher = CipherFactory::defaultFactory().createCipher(CipherKey(AES_NAME, "abcdef", "123456"));
std::string plainText = "This is my secret information";
std::string encrypted = uptrCipher->encryptString(plainText, Cipher::ENC_BASE64);
return 0;
}
If I run Valgrind I got this error (my apologize for the lengh):
valgrind --leak-check=full ./CipherTest
==32223== Memcheck, a memory error detector
==32223== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==32223== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==32223== Command: ./CipherTest
==32223==
==32223== Invalid free() / delete / delete[] / realloc()
==32223== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x5A3F369: __cxa_finalize (cxa_finalize.c:56)
==32223== by 0x687CAB2: ??? (in /usr/local/lib/libPocoFoundationd.so.48)
==32223== by 0x4010C16: _dl_fini (dl-fini.c:235)
==32223== by 0x5A3EFF7: __run_exit_handlers (exit.c:82)
==32223== by 0x5A3F044: exit (exit.c:104)
==32223== by 0x5A25836: (below main) (libc-start.c:325)
==32223== Address 0x737a9d0 is 0 bytes inside a block of size 20 free'd
==32223== at 0x4C2F24B: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x5A3F369: __cxa_finalize (cxa_finalize.c:56)
==32223== by 0x4ED7542: ??? (in /usr/local/lib/libPocoFoundation.so.48)
==32223== by 0x4010C16: _dl_fini (dl-fini.c:235)
==32223== by 0x5A3EFF7: __run_exit_handlers (exit.c:82)
==32223== by 0x5A3F044: exit (exit.c:104)
==32223== by 0x5A25836: (below main) (libc-start.c:325)
==32223== Block was alloc'd at
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x4F69C0C: ??? (in /usr/local/lib/libPocoFoundation.so.48)
==32223== by 0x4ED7212: ??? (in /usr/local/lib/libPocoFoundation.so.48)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223==
==32223== HEAP SUMMARY:
==32223== in use at exit: 73,124 bytes in 13 blocks
==32223== total heap usage: 3,914 allocs, 3,912 frees, 256,412 bytes allocated
==32223==
==32223== 18 bytes in 1 blocks are definitely lost in loss record 1 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F40D: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:31)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 20 bytes in 1 blocks are definitely lost in loss record 2 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F165: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:23)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 20 bytes in 1 blocks are definitely lost in loss record 3 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F1BA: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:24)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 20 bytes in 1 blocks are definitely lost in loss record 4 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x6942982: __static_initialization_and_destruction_0(int, int) (URI.cpp:32)
==32223== by 0x6942A63: _GLOBAL__sub_I_URI.cpp (URI.cpp:915)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 21 bytes in 1 blocks are definitely lost in loss record 5 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F3B8: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:30)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 25 bytes in 1 blocks are definitely lost in loss record 6 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F20F: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:25)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 25 bytes in 1 blocks are definitely lost in loss record 7 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F264: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:26)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 25 bytes in 1 blocks are definitely lost in loss record 8 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F2B9: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:27)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 25 bytes in 1 blocks are definitely lost in loss record 9 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F30E: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:28)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 25 bytes in 1 blocks are definitely lost in loss record 10 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x688F363: __static_initialization_and_destruction_0(int, int) (DateTimeFormat.cpp:29)
==32223== by 0x688FB4D: _GLOBAL__sub_I_DateTimeFormat.cpp (DateTimeFormat.cpp:63)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 28 bytes in 1 blocks are definitely lost in loss record 11 of 13
==32223== at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x558EAEC: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char const*>(char const*, char const*, std::forward_iterator_tag) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x558EC4B: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==32223== by 0x6918141: __static_initialization_and_destruction_0(int, int) (RotateStrategy.cpp:47)
==32223== by 0x69181B7: _GLOBAL__sub_I_RotateStrategy.cpp (RotateStrategy.cpp:115)
==32223== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==32223== by 0x40105FA: call_init (dl-init.c:30)
==32223== by 0x40105FA: _dl_init (dl-init.c:120)
==32223== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==32223==
==32223== 168 bytes in 1 blocks are definitely lost in loss record 12 of 13
==32223== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==32223== by 0x7038D9D: CRYPTO_zalloc (in /usr/local/lib/libcrypto.so.1.1)
==32223== by 0x5253907: Poco::Crypto::(anonymous namespace)::CryptoTransformImpl::CryptoTransformImpl(evp_cipher_st const*, std::vector<unsigned char, std::allocator<unsigned char> > const&, std::vector<unsigned char, std::allocator<unsigned char> > const&, Poco::Crypto::(anonymous namespace)::CryptoTransformImpl::Direction) (CipherImpl.cpp:100)
==32223== by 0x5253E6F: Poco::Crypto::CipherImpl::createEncryptor() (CipherImpl.cpp:218)
==32223== by 0x5252ACA: Poco::Crypto::Cipher::encrypt(std::istream&, std::ostream&, Poco::Crypto::Cipher::Encoding) (Cipher.cpp:67)
==32223== by 0x52528BB: Poco::Crypto::Cipher::encryptString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, Poco::Crypto::Cipher::Encoding) (Cipher.cpp:49)
==32223== by 0x4010FA: main (main.cpp:37)
==32223==
==32223== LEAK SUMMARY:
==32223== definitely lost: 420 bytes in 12 blocks
==32223== indirectly lost: 0 bytes in 0 blocks
==32223== possibly lost: 0 bytes in 0 blocks
==32223== still reachable: 72,704 bytes in 1 blocks
==32223== suppressed: 0 bytes in 0 blocks
==32223== Reachable blocks (those to which a pointer was found) are not shown.
==32223== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==32223==
==32223== For counts of detected and suppressed errors, rerun with: -v
==32223== ERROR SUMMARY: 23 errors from 13 contexts (suppressed: 0 from 0)
Following the last statements from the bottom, I went in the Cipher.cpp and CipherImp.cpp at the line #100 I found out:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
_pContext = EVP_CIPHER_CTX_new();
It seems is not deleted...I have no idea. But I'm sure that I'm making some mistakes.
Did anybody meet this error?
Where I wrong in the code?
Thank you
Cristano
I found out the answer.
It seems that with OpenSSL 1.1.0 the method to free resources is EVP_CIPHER_CTX_free(ctx).
I have included the CipherImpl in my project and changed the line below in the distructor:
CryptoTransformImpl::~CryptoTransformImpl()
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
//IT WAS: EVP_CIPHER_CTX_cleanup(_pContext);
EVP_CIPHER_CTX_free(_pContext);
#else
EVP_CIPHER_CTX_cleanup(&_context);
#endif
}
I ran again Valgrind:
valgrind --leak-check=full ./CipherTest
==32869== Memcheck, a memory error detector
==32869== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==32869== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==32869== Command: ./CipherTest
==32869==
Sono nel costruttore con Openssl v.269484127
==32869==
==32869== HEAP SUMMARY:
==32869== in use at exit: 72,704 bytes in 1 blocks
==32869== total heap usage: 3,893 allocs, 3,892 frees, 253,681 bytes allocated
==32869==
==32869== LEAK SUMMARY:
==32869== definitely lost: 0 bytes in 0 blocks
==32869== indirectly lost: 0 bytes in 0 blocks
==32869== possibly lost: 0 bytes in 0 blocks
==32869== still reachable: 72,704 bytes in 1 blocks
==32869== suppressed: 0 bytes in 0 blocks
==32869== Reachable blocks (those to which a pointer was found) are not shown.
==32869== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==32869==
==32869== For counts of detected and suppressed errors, rerun with: -v
==32869== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

"Corrupted double-linked list" when using malloc() on a 2D array in a structure

I'm trying to make a small autoCompletion program.
I'm taking strings from a file and put them line by line in a 2D char type array.
This is my code :
Dictionnary.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Dictionnary.h"
int getDictionnarySize(FILE *theDictionnary)
{
size_t pos = ftell(theDictionnary);
fseek(theDictionnary, 0, SEEK_END);
size_t len = ftell(theDictionnary);
fseek(theDictionnary, pos, SEEK_SET);
return (len);
}
int getNbLines(char *buff)
{
int lines = 1;
int i = 0;
while (buff[i] != '\0')
{
if (buff[i] == '\n')
lines++;
i++;
}
return (lines);
}
int allocDictionnary(t_dictionnary *d, char *buff)
{
d->lines = getNbLines(buff) - 1;
int i;
char str[2048];
int len;
rewind(d->dico);
d->dictionnary = malloc(sizeof(*d->dictionnary) * d->lines);
for (i = 0; i <= d->lines; i++)
{
memset(str, 0, 2048);
fgets(str, 256, d->dico);
len = strlen(str);
printf("len = %d\n", len);
d->dictionnary[i] = malloc(sizeof(**d->dictionnary) * len);
if (d->dictionnary[i] == NULL)
return (1);
strcpy(d->dictionnary[i], str);
printf("String is : %s\n", d->dictionnary[i]);
}
return (0);
}
int initDictionnary(t_dictionnary *d)
{
int size;
char *buff;
if ((d->dico = fopen(d->theDictionnary, "r")) != NULL)
{
size = getDictionnarySize(d->dico);
buff = malloc(size + 1);
fread(buff, size, 1, d->dico);
allocDictionnary(d, buff);
fclose(d->dico);
}
else
{
return (1);
}
free(buff);
return (0);
}
int killDictionnary(char **theDictionnary, int size)
{
int i = 0;
while (i <= size)
{
free(theDictionnary[i]);
i++;
}
free(theDictionnary);
return (0);
}
Dictionnary.h
#ifndef __DICTIONNARRY_H__
# define __DICTIONNARY_H___
/* STRUCTURES */
typedef struct s_dictionnary
{
const char *theDictionnary;
FILE *dico;
char **dictionnary;
int lines;
} t_dictionnary;
/* PROTOTYPES */
int getDictionnarySize(FILE *theDictionnary);
int allocDictionnary(t_dictionnary *d, char *buff);
int initDictionnary(t_dictionnary *dico);
int getNbLines(char *buff);
int killDictionnary(char **theDictionnary, int size);
#endif /* __DICTIONNARY_H__ */
main.c
#include <stdlib.h>
#include <stdio.h>
#include "Dictionnary.h"
int main(int ac, char **av)
{
t_dictionnary d;
d.theDictionnary = "./miniDico";
initDictionnary(&d);
killDictionnary(d.dictionnary, d.lines);
return (0);
}
When I compile, i don't have any errors or warnings.
But when I run this I get :
*** Error in `./a.out': corrupted double-linked list: 0x0000000000f19550 ***
Valgrind result :
==4004== Memcheck, a memory error detector
==4004== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==4004== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==4004== Command: ./a.out
==4004==
==4004== Conditional jump or move depends on uninitialised value(s)
==4004== at 0x40095C: getNbLines (Dictionnary.c:22)
==4004== by 0x40098B: allocDictionnary (Dictionnary.c:34)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
len = 35
==4004== Invalid write of size 1
==4004== at 0x4C2D623: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x400AB8: allocDictionnary (Dictionnary.c:50)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d8723 is 0 bytes after a block of size 35 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x400A61: allocDictionnary (Dictionnary.c:47)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 1
==4004== at 0x4E7E1C2: vfprintf (in /usr/lib/libc-2.21.so)
==4004== by 0x4E84E38: printf (in /usr/lib/libc-2.21.so)
==4004== by 0x400AE5: allocDictionnary (Dictionnary.c:51)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d8723 is 0 bytes after a block of size 35 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x400A61: allocDictionnary (Dictionnary.c:47)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
String is : Paris, 458 boulevard Saint-Germain
len = 35
String is : Paris, 343 boulevard Saint-Germain
len = 44
String is : Marseille, 343 boulevard Camille Flammarion
len = 37
String is : Marseille, 29 rue Camille Desmoulins
len = 34
String is : Marseille, 1 chemin des Aubagnens
len = 25
String is : Paris, 12 rue des singes
len = 24
String is : Paris, 34 quai VoLtAiRe
len = 23
String is : Paris, 34 rue Voltaire
len = 33
String is : Lille, 120 boulevard Victor Hugo
len = 27
String is : Marseille, 50 rue Voltaire
len = 26
String is : Toulouse, 90 rue Voltaire
len = 30
String is : Strasbourg 84 rue du Bouclier
len = 42
String is : Marseille, 78 boulevard de la libération
len = 27
String is : Lille, 30 rue Victor Danel
len = 38
String is : Mont Saint Martin, 42 rue de Bordeaux
len = 47
String is : Mont de Marsan, 100 avenue Pierre de Coubertin
len = 35
String is : Strasbourg, 391 boulevard de Nancy
len = 38
String is : Lyon, 56 rue du Docteur Albéric Pont
len = 35
String is : Lyon, rue du Docteur Albéric Pont
len = 38
String is : 56 rue du Docteur Albéric Pont, Lyon
len = 19
String is : Lyon 56 grande rue
len = 24
String is : Lille, 90 rue d’Arras
len = 35
String is : Lille, 76 impasse Georges Pompidou
len = 25
==4004== Invalid write of size 8
==4004== at 0x400A62: allocDictionnary (Dictionnary.c:47)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 8
==4004== at 0x400A7D: allocDictionnary (Dictionnary.c:48)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 8
==4004== at 0x400AA4: allocDictionnary (Dictionnary.c:50)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004== Invalid read of size 8
==4004== at 0x400AD1: allocDictionnary (Dictionnary.c:51)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
String is : Lyon, 2 allée des fleurs
==4004== Invalid read of size 8
==4004== at 0x400BF6: killDictionnary (Dictionnary.c:85)
==4004== by 0x400C53: main (main.c:11)
==4004== Address 0x51d86b8 is 0 bytes after a block of size 184 alloc'd
==4004== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4004== by 0x4009C3: allocDictionnary (Dictionnary.c:40)
==4004== by 0x400B9F: initDictionnary (Dictionnary.c:67)
==4004== by 0x400C42: main (main.c:10)
==4004==
==4004==
==4004== HEAP SUMMARY:
==4004== in use at exit: 0 bytes in 0 blocks
==4004== total heap usage: 27 allocs, 27 frees, 2,289 bytes allocated
==4004==
==4004== All heap blocks were freed -- no leaks are possible
==4004==
==4004== For counts of detected and suppressed errors, rerun with: -v
==4004== Use --track-origins=yes to see where uninitialised values come from
==4004== ERROR SUMMARY: 54 errors from 8 contexts (suppressed: 0 from 0)
Maybe this loop causing troubles:
for (i = 0; i <= d->lines; i++)
It seems that it should be (I've changed stop condition):
for (i = 0; i < d->lines; i++)
otherwise you write behind allocated space...
UPDATE
Clarification:
Allocating array with d->dictionnary = malloc(sizeof(*d->dictionnary) * d->lines); gives you an arry with exactly d->lines elements. It starts from 0 index and last element could be accessed with d->lines-1 index. So when you use loop from 0 up to and including d->lines the very last loop cycle will write outside of array boundaries (i.e. to d->lines index). That's where you corrup your heap. Very often C runtime doesn't check for such errors and you will only see them on rare ocasions and probably far away from the code which caused them.
"corrupted linked list" is about heap corruption. Blocks allocated with malloc are usually chained into linked lists (this really depends on implementation of you memory allocator). So, when writing outside allocation boundaries - you can corrupt this list. Hence the complaint.

Resources