1

我有两个文件:

// event_test_delete.cpp
#include <event.h>

int main() {
        event_base* ev;

        ev = event_init();
        delete ev;

        return 0; 
}

// event_test_free.cpp
#include <event.h>
#include <cstdlib>

int main() {
        event_base* ev;

        ev = event_init();
        free(ev);

        return 0; 
}

当我编译(g++ event_test_delete.cpp -levent -o event_test_delete.o) event_test_delete.cpp 时,我得到一个错误

event_test_delete.cpp:在函数“int main()”中:
event_test_delete.cpp:8:9:警告:在调用删除运算符时检测到可能的问题:
event_test_delete.cpp:5:14:警告:“ev”类型不完整
/usr/include/event.h:211:8: 警告: 'struct event_base' 的前向声明
event_test_delete.cpp:8:9: 注意:析构函数和特定于类的操作符 delete 都不会被调用,即使它们是在定义类时声明的。

但是当我编译g++ event_test_free.cpp -levent -o event_test_free.oevent_test_free.cpp 我没有得到同样的错误,为什么?

第二个问题是(使用 valgrind)为什么会出现内存泄漏?

第一个文件的 Valgrind 输出:(为什么这里是一个Mismatched free() / delete / delete []?)

azat:~/Desktop/event_test$ valgrind --show-reachable=yes --leak-check=full ./event_test_delete.o
==4135== Memcheck,内存错误检测器
==4135== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4135== 使用 Valgrind-3.6.0.SVN-Debian 和 LibVEX;使用 -h 重新运行以获取版权信息
==4135== 命令:./event_test_delete.o
==4135==
==4135== 不匹配的 free() / delete / delete []
==4135== 在 0x4023881:操作员删除(void*)(vg_replace_malloc.c:387)
==4135== by 0x8048571: main (in /home/azat/Desktop/event_test/event_test_delete.o)
==4135== 地址 0x4323028 是分配的大小为 944 的块内的 0 个字节
==4135== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== 0x4047DA7:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== by 0x4047EF6: event_init (在/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== 堆摘要:
==4135== 在退出时使用:5 个块中的 672 个字节
==4135== 总堆使用量:6 次分配,1 次释放,分配 1,616 字节
==4135==
==4135== 1 个块中的 8 个字节在丢失记录 1 of 5 中间接丢失
==4135== 在 0x4023F50:malloc (vg_replace_malloc.c:236)
==4135== 由 0x4047C7D:event_base_priority_init(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== by 0x4047E8B: event_base_new (在/usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (在/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== 1 个块中的 12 个(4 个直接,8 个间接)字节在 5 个丢失记录 2 中肯定丢失
==4135== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== by 0x4047C2D: event_base_priority_init (在/usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047E8B: event_base_new (在/usr/lib/libevent-1.4.so.2.1.3)
==4135== by 0x4047EF6: event_init (在/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== 1 个块中的 256 个字节在丢失记录 3 of 5 中间接丢失
==4135== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== 由 0x4056192: ??? (在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== 0x4047E46:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== by 0x4047EF6: event_init (在/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== 1 个块中的 384 个字节在丢失记录 4 of 5 中间接丢失
==4135== 在 0x4023F50:malloc (vg_replace_malloc.c:236)
==4135== 由 0x405616C: ??? (在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== 0x4047E46:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== by 0x4047EF6: event_init (在/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== 1 个块中的 660(20 个直接,640 个间接)字节在丢失记录 5 of 5 中肯定丢失了
==4135== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4135== 由 0x4056157: ??? (在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== 0x4047E46:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4135== by 0x4047EF6: event_init (在/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== 肯定丢失:2 个块中的 24 个字节
==4135==间接丢失:3块648字节
==4135== 可能丢失:0 个块中的 0 个字节
==4135== 仍然可达:0 个块中的 0 个字节
==4135== 抑制:0 个块中的 0 个字节
==4135==
==4135== 对于检测到和抑制的错误计数,重新运行:-v
==4135== 错误摘要:3 个上下文中的 3 个错误(抑制:7 个中的 28 个)

对于第二个文件

azat:~/Desktop/event_test$ valgrind --show-reachable=yes --leak-check=full ./event_test_free.o
==4140== Memcheck,内存错误检测器
==4140== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==4140== 使用 Valgrind-3.6.0.SVN-Debian 和 LibVEX;使用 -h 重新运行以获取版权信息
==4140== 命令:./event_test_free.o
==4140==
==4140==
==4140== 堆摘要:
==4140== 退出时使用:5 个块中的 672 个字节
==4140== 总堆使用量:6 次分配,1 次释放,分配 1,616 字节
==4140==
==4140== 1 个块中的 8 个字节在丢失记录 1 of 5 中间接丢失
==4140== 在 0x4023F50:malloc (vg_replace_malloc.c:236)
==4140== 由 0x4047C7D:event_base_priority_init(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== by 0x4047E8B: event_base_new (在/usr/lib/libevent-1.4.so.2.1.3)
==4140== 由 0x4047EF6:event_init(在 /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== 1 个块中的 12 个(4 个直接,8 个间接)字节在 5 个丢失记录 2 中肯定丢失
==4140== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4140== 由 0x4047C2D:event_base_priority_init(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== by 0x4047E8B: event_base_new (在/usr/lib/libevent-1.4.so.2.1.3)
==4140== 由 0x4047EF6:event_init(在 /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== 1 个块中的 256 个字节在丢失记录 3 of 5 中间接丢失
==4140== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4140== 由 0x4056192: ??? (在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== 0x4047E46:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== 由 0x4047EF6:event_init(在 /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== 1 个块中的 384 个字节在丢失记录 4 of 5 中间接丢失
==4140== 在 0x4023F50:malloc (vg_replace_malloc.c:236)
==4140== 由 0x405616C: ??? (在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== 0x4047E46:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== 由 0x4047EF6:event_init(在 /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== 1 个块中的 660(20 个直接,640 个间接)字节在 5 个丢失记录 5 中肯定丢失
==4140== 在 0x402328F: calloc (vg_replace_malloc.c:467)
==4140== 由 0x4056157: ??? (在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== 0x4047E46:event_base_new(在 /usr/lib/libevent-1.4.so.2.1.3 中)
==4140== 由 0x4047EF6:event_init(在 /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== 泄漏摘要:
==4140== 肯定丢失:2 个块中的 24 个字节
==4140==间接丢失:3块648字节
==4140== 可能丢失:0 个块中的 0 个字节
==4140== 仍然可以访问:0 个块中的 0 个字节
==4140== 抑制:0 个块中的 0 个字节
==4140==
==4140== 对于检测到和抑制的错误计数,重新运行:-v
==4140== 错误摘要:来自 2 个上下文的 2 个错误(抑制:7 个中的 28 个)
4

3 回答 3

2

编译器在使用时delete需要查看指向的对象的类型,以确定是否有任何析构函数需要在该点调用。

另一方面,valgrind 似乎说内存是使用 malloc 和 calloc 分配的。在这种情况下,您根本不应该使用delete,但也许free.

在第二种情况下,当使用freevalgrind 时,仍然会抱怨内存泄漏。这里的一种可能性是事件对象包含指向也需要释放的其他分配的指针。

在这种情况下,应该有另一个函数event_free或者event_release您应该调用,以返回事件对象。你有其中之一吗?

于 2011-05-06T09:34:54.770 回答
1

第一个问题:delete 需要知道它删除的指针的类型,因为它可能需要调用析构函数。

秒问题:请参阅问题下方的评论。我们需要知道 event_init 做了什么以及它如何分配内存来建议现有的内存泄漏。然而,一个好建议:相信 Valgrind。

于 2011-05-06T09:26:15.923 回答
0

Libevent 不是用 C++ 编写的,因此它不使用析构函数。你永远不应该delete在没有被分配的代码上使用new.

如果您阅读“解除分配事件库”下的 libevent手册,则说明您应该使用:

void event_base_free(struct event_base *base);

此外,不推荐使用event_new分配事件库的函数(因为它不是线程安全的),您应该改用:

struct event_base *event_base_new(void);
于 2012-11-15T13:24:38.080 回答