Memory leak while handling exceptions - c++

I just move to C++ from C, and currently slicing my path through exceptions.
I'm having a hard time figuring out why am I getting a memory leak in this simple program:
#include <iostream> /* I/O */
#include <exception> /* exception */
#include <cstdlib> /* stdlib */
using namespace std;
void Bar()
{
throw exception();
}
void Foo()
{
int *ip = new int;
try
{
Bar();
}
catch(exception &e)
{
cerr << "Foo: Exception caught: " << e.what() << endl;
delete ip;
exit(1);
}
delete ip;
}
int main()
{
Foo();
return 0;
}
I feel like I'm missing something crucial here, but can't point at it. Any idea?
Valgrind's output:
==21857== Memcheck, a memory error detector
==21857== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==21857== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==21857== Command: ./a.out
==21857==
Foo: Exception caught: std::exception
==21857==
==21857== HEAP SUMMARY:
==21857== in use at exit: 136 bytes in 1 blocks
==21857== total heap usage: 3 allocs, 2 frees, 72,844 bytes allocated
==21857==
==21857== 136 bytes in 1 blocks are possibly lost in loss record 1 of 1
==21857== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==21857== by 0x4ECD8FF: __cxa_allocate_exception (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==21857== by 0x108CCC: Bar() (ex33.cpp:9)
==21857== by 0x108D0C: Foo() (ex33.cpp:18)
==21857== by 0x108DBD: main (ex33.cpp:31)
==21857==
==21857== LEAK SUMMARY:
==21857== definitely lost: 0 bytes in 0 blocks
==21857== indirectly lost: 0 bytes in 0 blocks
==21857== possibly lost: 136 bytes in 1 blocks
==21857== still reachable: 0 bytes in 0 blocks
==21857== suppressed: 0 bytes in 0 blocks
==21857==
==21857== For counts of detected and suppressed errors, rerun with: -v
==21857== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

You should't call exit in C++ really. Local objects destructors will not be called. And cause stack will not be unwounded, looks like destructor of exception also will not be called.
From standard:
18.1.2 When an exception is thrown, control is transferred to the nearest handler with a matching type (18.3); “nearest” means the
handler for which the compound-statement or ctor-initializer following
the try keyword was most recently entered by the thread of control and
not yet exited
18.1.3 Throwing an exception copy-initializes (11.6, 15.8) a temporary object, called the exception object. An lvalue denoting the temporary
is used to initialize the variable declared in the matching handler
(18.3). If the type of the exception object would be an incomplete
type or a pointer to an incomplete type other than cv void the program
is ill-formed.
Stack is not unwound: destructors of variables with automatic storage duration are not called. Quote from here

As it turned out, replacing exit(1) from within Foo() to return; fixed the memory leak.
So, my follow-up question, why can't I call exit() from Foo()?

Related

Load shared lib in c++ causes segmentation fault

I am learning c++, and am experimenting with loading a shared lib on linux (.so).
I get a segmentation fault when I run the below code.
When I try to run the console app using valgrind, I get the following:
valgrind ./TestLoadSo --leak-check=full -v
==26828== Memcheck, a memory error detector
==26828== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==26828== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==26828== Command: ./TestLoadSo --leak-check=full -v
==26828==
!!!Hello World!!!
==26828== Jump to the invalid address stated on the next line
==26828== at 0x0: ???
==26828== by 0x53E63F0: (below main) (libc-start.c:291)
==26828== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==26828==
==26828==
==26828== Process terminating with default action of signal 11 (SIGSEGV)
==26828== Bad permissions for mapped region at address 0x0
==26828== at 0x0: ???
==26828== by 0x53E63F0: (below main) (libc-start.c:291)
==26828==
==26828== HEAP SUMMARY:
==26828== in use at exit: 3,126 bytes in 9 blocks
==26828== total heap usage: 13 allocs, 4 frees, 76,998 bytes allocated
==26828==
==26828== LEAK SUMMARY:
==26828== definitely lost: 0 bytes in 0 blocks
==26828== indirectly lost: 0 bytes in 0 blocks
==26828== possibly lost: 0 bytes in 0 blocks
==26828== still reachable: 3,126 bytes in 9 blocks
==26828== suppressed: 0 bytes in 0 blocks
==26828== Rerun with --leak-check=full to see details of leaked memory
==26828==
==26828== For counts of detected and suppressed errors, rerun with: -v
==26828== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
[1] 26828 segmentation fault (core dumped) valgrind ./TestLoadSo --leak-check=full -v
C++ Main class
extern "C" typedef char* (*helloWorld_t)();
int main() {
void* handle = dlopen("./libMyLib.dll.so", RTLD_LAZY);
if (!handle) {
cerr << "Cannot open library: " << dlerror() << '\n';
return 1;
}
helloWorld_t hello = (helloWorld_t)dlsym( handle, "helloWorld" );
const char * tmp = hello();
printf("\n%s",tmp);
return 0;
}
The extern function is:
extern "C++" char* helloWorld() {
char str[25];
strcpy(str, "HelloWorld");
}
If I use extern "C" I get a compilation error:
error: conflicting declaration of ‘char* helloWorld()’ with ‘C’ linkage
extern "C" char* helloWorld() {
Its really not clear to me where I am going wrong.
A function cannot have both C and C++ linkage, and a function pointer type must match its target function's linkage.
You cannot dlsym an extern "C++" function by its unadorned name. You have to either use extern "C" in both cases (recommended), or use extern "C++" throughout and replace the string in dlsym(handle, "helloWorld") with the mangled name of your function (not recommended).
Always check the result of dlsym and report an error if it returns a null pointer (use dlerror() like you've done for dlopen).
Don't use character arrays or pointers to represent strings. There is a type for string, called std::string.
Last but not least, always compile with -Wall -Werror so things like a non-void function that doesn't actually return a value will be caught.
Many problems here:
extern "C++" char* helloWorld() {
char str[25];
strcpy(str, "HelloWorld");
}
It should use "C" linkage. And it should return something. And it copies the string to local variable, so value gets lost when it returns. So probably
extern "C" char* helloWorld() {
static char str[25]; // will keep its value accross calls, not thread safe
return strcpy(str, "HelloWorld"); // return pointer to start of str
}
Note that multiple calls all return same static buffer. If you need copies, you need to let caller provide a buffer, or return buffer allocated with malloc.

Valgrind tool for GDB

int main()
{
char *p;
p = malloc(10);
delete(p);
return;
}
what will be appropriate error detected by Valgrind?
First of all this code snippet gives two compilation errors,
In function ‘int main()’:
error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
p = malloc(10);
^
error: return-statement with no value, in function returning ‘int’ [- fpermissive]
return;
Correct the code with these changes,
Type cast while allocating memory using malloc, as shown here.
p = (char*) malloc(10);
The return type of main function is int, so change the return value accordingly, as mentioned here.
return 0; // Use return 0, instead of just return.
Before using delete operation, do a validity check on the pointer, as shown here.
if(p)
delete(p);
With the above changes, and upon successful compilation of the above code. Use the valgrind tool to run the above sample.
As such there is no issue in the code, so valgrind did not find any issue. Below is sample valgrind output.
Valgrind output:
==30050== Memcheck, a memory error detector
==30050== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==30050== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==30050== Command: ./valgrindtest
==30050==
main Start
==30050== Mismatched free() / delete / delete []
==30050== at 0x4C2C18D: operator delete(void*) (vg_replace_malloc.c:576)
==30050== by 0x4006E0: main (valgrindtest.cpp:16)
==30050== Address 0x5a1b040 is 0 bytes inside a block of size 10 alloc'd
==30050== at 0x4C2ABE3: malloc (vg_replace_malloc.c:299)
==30050== by 0x4006C2: main (valgrindtest.cpp:11)
==30050==
main End
==30050==
==30050== HEAP SUMMARY:
==30050== in use at exit: 0 bytes in 0 blocks
==30050== total heap usage: 1 allocs, 1 frees, 10 bytes allocated
==30050==
==30050== All heap blocks were freed -- no leaks are possible
==30050==
==30050== For counts of detected and suppressed errors, rerun with: -v
==30050== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Cannot find memory leak detected by Valgrind

I'm running and analyzing with Valgrind this code:
int main() {
Set<int> c;
return 0;
}
So the output is:
jscherman#jscherman:~/ClionProjects/algo2-t3-bts$ g++ set.hpp tests.cpp && valgrind --leak-check=yes --show-leak-kinds=all ./a.out
==3528== Memcheck, a memory error detector
==3528== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==3528== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==3528== Command: ./a.out
==3528==
test_mleak...ok
==3528==
==3528== HEAP SUMMARY:
==3528== in use at exit: 72,704 bytes in 1 blocks
==3528== total heap usage: 2 allocs, 1 frees, 73,728 bytes allocated
==3528==
==3528== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==3528== at 0x4C2DC10: malloc (vg_replace_malloc.c:299)
==3528== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==3528== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==3528== by 0x40105FA: call_init (dl-init.c:30)
==3528== by 0x40105FA: _dl_init (dl-init.c:120)
==3528== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==3528==
==3528== LEAK SUMMARY:
==3528== definitely lost: 0 bytes in 0 blocks
==3528== indirectly lost: 0 bytes in 0 blocks
==3528== possibly lost: 0 bytes in 0 blocks
==3528== still reachable: 72,704 bytes in 1 blocks
==3528== suppressed: 0 bytes in 0 blocks
==3528==
==3528== For counts of detected and suppressed errors, rerun with: -v
==3528== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Apparently, i'm loosing memory at the constructor of Set, but i can't find the actual reason. This is how i implemented Set (in a BTS):
template<class T>
class Set {
public:
Set() : root_(NULL), cardinal_(0) {}
~Set() {delete root_;}
void insert(const T &);
bool belongs(const T &) const;
void remove(const T &);
const T &min() const;
const T &max() const;
unsigned int cardinal() const;
private:
struct Node {
Node(const T &v) : value(v), left(NULL), right(NULL) {}
~Node() {delete right; delete left;}
T value;
Node *left;
Node *right;
};
Node *root_;
int cardinal_;
}
Any idea how to solve this leak? Thanks!
You're not leaking anything--you're just misunderstanding what valgrind is telling you.
It thinks there may be some problem underneath _dl_init(), but this is a red herring. You can safely add it to your valgrind suppressions file (which is always a good thing to have, so you aren't bothered by false alarms from system libraries).

unclear memory leak with vector, c++, when calling exit

I was debugging my program and I've noticed that even though I've marked almost all of
it as comment and all I did was to push double values into a vector, I have a memory leak. I read the api in c++ reference, but couldn't find anything. Here's the code:
#include <vector>
#include <cstdlib>
#include <iostream>
#include "RegMatrix.h"
#include "Matrix.h"
using namespace std;
int main(void)
{
vector<double> v;
for (int i=0; i<9; i++)
{
v.push_back(i);
}
cout << endl;
exit(EXIT_SUCCESS);
}
And valgrind's report:
==9299== HEAP SUMMARY:
==9299== in use at exit: 128 bytes in 1 blocks
==9299== total heap usage: 5 allocs, 4 frees, 248 bytes allocated
==9299==
==9299== 128 bytes in 1 blocks are still reachable in loss record 1 of 1
==9299== at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255)
==9299== by 0x804937D: __gnu_cxx::new_allocator<double>::allocate(unsigned int, void const*) (in /home/yotamoo/workspace/ex3/main)
==9299== by 0x804922F: std::_Vector_base<double, std::allocator<double> >::_M_allocate(unsigned int) (in /home/yotamoo/workspace/ex3/main)
==9299== by 0x8048E6C: std::vector<double, std::allocator<double> >::_M_insert_aux(__gnu_cxx::__normal_iterator<double*, std::vector<double, std::allocator<double> > >, double const&) (in /home/yotamoo/workspace/ex3/main)
==9299== by 0x8048CA2: std::vector<double, std::allocator<double> >::push_back(double const&) (in /home/yotamoo/workspace/ex3/main)
==9299== by 0x8048B10: main (in /home/yotamoo/workspace/ex3/main)
==9299==
==9299== LEAK SUMMARY:
==9299== definitely lost: 0 bytes in 0 blocks
==9299== indirectly lost: 0 bytes in 0 blocks
==9299== possibly lost: 0 bytes in 0 blocks
==9299== still reachable: 128 bytes in 1 blocks
==9299== suppressed: 0 bytes in 0 blocks
This is weird. Any ideas? thanks
exit() will not call the destructors of the current scope thus there may be a leak:
(§3.6.1/4) Calling the function void exit(int); declared in <cstdlib> (18.3) terminates the program without leaving the current block and hence without destroying any objects with automatic storage duration (12.4). If exit is called to end a program during the destruction of an object with static storage duration, the program has undefined behavior.
Use this instead:
#include <vector>
#include <iostream>
int main(int argc, char *argv[]) {
std::vector<double> v;
for (int i=0; i<9; i++) {
v.push_back(i);
}
std::cout << endl;
return 0;
}
The vector never goes out of scope for the exit.
Just remove the exit() from main and replace it with a return 0;
I don't believe that you have a memory leak. When valgrind says the memory is still reachable it's not telling you that it leaked but that it wasn't free'ed before the program exited. In this case the vector desctructor didn't get called before exit. Try returning from main rather than calling exit().
Did you try putting all the code except exit in a separate {} block?
You did not have to call the exit function it will immediate exit from the program did not call the OS clean up calls.
Always use the return() not exit().

C++ libevent usage (memory leak and delete operator)

I have two files:
// event_test_delete.cpp
#include <event.h>
int main() {
event_base* ev;
ev = event_init();
delete ev;
return 0;
}
And
// event_test_free.cpp
#include <event.h>
#include <cstdlib>
int main() {
event_base* ev;
ev = event_init();
free(ev);
return 0;
}
When I compile (g++ event_test_delete.cpp -levent -o event_test_delete.o) event_test_delete.cpp I get an error:
event_test_delete.cpp: In function ‘int main()’:
event_test_delete.cpp:8:9: warning: possible problem detected in invocation of delete operator:
event_test_delete.cpp:5:14: warning: ‘ev’ has incomplete type
/usr/include/event.h:211:8: warning: forward declaration of ‘struct event_base’
event_test_delete.cpp:8:9: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
But when I compile g++ event_test_free.cpp -levent -o event_test_free.o event_test_free.cpp I don`t get the same error why?
And the second question is (using valgrind) why there is a memory leak?
Valgrind output for first file: (why here is an Mismatched free() / delete / delete [] ?)
azat:~/Desktop/event_test$ valgrind --show-reachable=yes --leak-check=full ./event_test_delete.o
==4135== Memcheck, a memory error detector
==4135== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4135== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4135== Command: ./event_test_delete.o
==4135==
==4135== Mismatched free() / delete / delete []
==4135== at 0x4023881: operator delete(void*) (vg_replace_malloc.c:387)
==4135== by 0x8048571: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135== Address 0x4323028 is 0 bytes inside a block of size 944 alloc'd
==4135== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== by 0x4047DA7: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135==
==4135==
==4135== HEAP SUMMARY:
==4135== in use at exit: 672 bytes in 5 blocks
==4135== total heap usage: 6 allocs, 1 frees, 1,616 bytes allocated
==4135==
==4135== 8 bytes in 1 blocks are indirectly lost in loss record 1 of 5
==4135== at 0x4023F50: malloc (vg_replace_malloc.c:236)
==4135== by 0x4047C7D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135==
==4135== 12 (4 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 5
==4135== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== by 0x4047C2D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135==
==4135== 256 bytes in 1 blocks are indirectly lost in loss record 3 of 5
==4135== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== by 0x4056192: ??? (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135==
==4135== 384 bytes in 1 blocks are indirectly lost in loss record 4 of 5
==4135== at 0x4023F50: malloc (vg_replace_malloc.c:236)
==4135== by 0x405616C: ??? (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135==
==4135== 660 (20 direct, 640 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
==4135== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== by 0x4056157: ??? (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x8048561: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135==
==4135== LEAK SUMMARY:
==4135== definitely lost: 24 bytes in 2 blocks
==4135== indirectly lost: 648 bytes in 3 blocks
==4135== possibly lost: 0 bytes in 0 blocks
==4135== still reachable: 0 bytes in 0 blocks
==4135== suppressed: 0 bytes in 0 blocks
==4135==
==4135== For counts of detected and suppressed errors, rerun with: -v
==4135== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 28 from 7)
And for second file
azat:~/Desktop/event_test$ valgrind --show-reachable=yes --leak-check=full ./event_test_free.o
==4140== Memcheck, a memory error detector
==4140== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4140== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==4140== Command: ./event_test_free.o
==4140==
==4140==
==4140== HEAP SUMMARY:
==4140== in use at exit: 672 bytes in 5 blocks
==4140== total heap usage: 6 allocs, 1 frees, 1,616 bytes allocated
==4140==
==4140== 8 bytes in 1 blocks are indirectly lost in loss record 1 of 5
==4140== at 0x4023F50: malloc (vg_replace_malloc.c:236)
==4140== by 0x4047C7D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o)
==4140==
==4140== 12 (4 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 5
==4140== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4140== by 0x4047C2D: event_base_priority_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047E8B: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o)
==4140==
==4140== 256 bytes in 1 blocks are indirectly lost in loss record 3 of 5
==4140== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4140== by 0x4056192: ??? (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o)
==4140==
==4140== 384 bytes in 1 blocks are indirectly lost in loss record 4 of 5
==4140== at 0x4023F50: malloc (vg_replace_malloc.c:236)
==4140== by 0x405616C: ??? (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o)
==4140==
==4140== 660 (20 direct, 640 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5
==4140== at 0x402328F: calloc (vg_replace_malloc.c:467)
==4140== by 0x4056157: ??? (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047E46: event_base_new (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x4047EF6: event_init (in /usr/lib/libevent-1.4.so.2.1.3)
==4140== by 0x8048531: main (in /home/azat/Desktop/event_test/event_test_free.o)
==4140==
==4140== LEAK SUMMARY:
==4140== definitely lost: 24 bytes in 2 blocks
==4140== indirectly lost: 648 bytes in 3 blocks
==4140== possibly lost: 0 bytes in 0 blocks
==4140== still reachable: 0 bytes in 0 blocks
==4140== suppressed: 0 bytes in 0 blocks
==4140==
==4140== For counts of detected and suppressed errors, rerun with: -v
==4140== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 28 from 7)
When using delete the compiler needs to see the type of the object pointed to, to determine if there are any destructors it needs to call at that point.
On the other hand, valgrind seems to say that the memory is allocated using malloc and calloc. In that case, you should not use delete at all, but perhaps free.
In the second case, when using free, valgrind still complains on memory leaks. One possibility here is that the event object contains pointers to other allocations that also need to be freed.
In that case, there should be another function event_free or event_release you should call, to return the event object. Do you have one of those?
First Question: delete needs to know the type of the pointer it deletes, since it might need to call a destructor.
Seconds Question: see the comment below the question. We need to know what event_init does and how it allocates the memory to advice about existing memory leaks. However, a good advice: Trust Valgrind.
Libevent is not written in C++, and hence it does not use destructors. You should never use delete on code that hasn't been allocated using new.
If you read the libevent manual under "deallocating an event base" it states that you should use:
void event_base_free(struct event_base *base);
Also the event_new function for allocating an event base is deprecated (since it's not thread safe), you should instead use:
struct event_base *event_base_new(void);