0

我写了一个套接字服务器。我意识到当我在它运行时按下 Ctrl-C 时,可能存在内存泄漏。我用 valgrind 找到了这个。

我的服务器代码很简单。基本上我创建了一个 Listener 对象,启动一个线程来接受连接并尝试加入该线程:

 try {
    Server::Listener listener(1234);

    boost::thread l(boost::bind(&Server::Listener::start, &listener));

    l.join();

} catch(exception& e) {
    cout<<e.what()<<endl;
}

当我运行 valgrind 时,它给了我:

==3580== 命令:bin/Debug/p_rpc
==3580==
Listner 已启动...
在循环中..
^C==3580==
==3580== HEAP 摘要:
==3580== 在退出时使用: 24 个块中的 3,176 个字节
==3580== 总堆使用量:28 个分配,4 个释放,分配的 4,328 个字节
==3580==
==3580== 1 个块中的 288 个字节可能在 24 个丢失记录 21 中丢失
== 3580== 在 0x4C29E46:calloc(在 /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)==3580==
由 0x4012084:_dl_allocate_tls(dl-tls.c:297)
==3580== 由 0x4E3AABC: pthread_create@@GLIBC_2.2.5 (allocatestack.c:571)
==3580== by 0x5260F9F: boost::thread::start_thread() (in
/usr/lib/libboost_thread.so.1.49.0) ==3580== by 0x407B93: boost::thread::thread, boost::_bi::list1 > > >(boost::_bi::bind_t, boost: :_bi::list1 > >&&) (thread.hpp:171)
==3580== by 0x404CA4: main (main.cpp:179)
==3580==
==3580== 泄漏总结:
==3580==肯定丢失:0 个块中的 0 个字节
==3580== 间接丢失:0 个块中的 0 个字节
==3580== 可能丢失:1 个块中的 288 个字节
==3580== 仍然可以访问:23 个块中的 2,888 个字节
==3580 == 抑制:0 个块中的 0 个字节
==3580== 未显示可达块(找到指针的块)。
==3580== 要查看它们,请重新运行: --leak-check=full --show-reachable=yes
==3580==
==3580== 对于检测到和抑制的错误计数,重新运行:-v
==3580== 错误摘要:1 个上下文中的 1 个错误(抑制:2 个中的 2 个)
已杀死

它指出可能丢失了 288 字节。我想我可以使用信号处理程序来释放这个资源。但我不知道我是怎么做到的。你能给我一个例子吗?

干杯,埃尔顿

4

2 回答 2

2

当一个进程关闭时,操作系统会自动清理该进程拥有的所有内存。您无需担心程序退出时释放该内存。该建筑正在拆除。不要费心扫地、清空垃圾桶和擦白板。并且不要在建筑物的出口排队,这样每个人都可以将他们的进/出磁铁移到外面。你所做的只是让拆迁队等你完成这些毫无意义的大扫除任务。

确实需要担心的泄漏类型是在程序生命周期内不断泄漏的泄漏。

于 2013-01-29T22:52:01.860 回答
1

原则上,您可以在那里销毁对象。您可以在信号处理程序中执行的操作受到限制,并且它们与线程的混合非常糟糕。请注意,在这方面编译器可以不做或很少)检查,信号处理程序只是一个普通函数。要格外小心。

这个问题的答案提供了一些关于如何做到这一点的细节。

于 2013-01-29T23:02:08.740 回答