【发布时间】:2015-08-11 01:39:07
【问题描述】:
我在 c++ 中有一个回调函数,它可以做到这一点:
void MasterInterface::zsock_cb(struct ev_loop *loop, ev_zsock_t *wz, int revents) {
char iden[MAX_MSG_LEN];
char msg[MAX_MSG_LEN];
int numIDBytes = zmq_recv(wz->zsock, iden, sizeof(iden), 0);
int numBytes = zmq_recv(wz->zsock, msg, sizeof(msg), 0);
masterStruct* mStruct = (masterStruct*)wz->data;
std::string idenData = std::string(static_cast<char*>(iden), numIDBytes);
std::string msgData = std::string(static_cast<char*>(msg), numBytes);
cout << "[IN] " << msgData << endl;
if (!mStruct->synchronized) {
if (!IDRegistered(mStruct, idenData)) {
cout << "[IN] " << idenData << endl;
cout << "[IN] " << msgData << endl;
mStruct->slaveIDs[mStruct->counter++] = idenData;
zmq_send (wz->zsock, idenData.c_str(), idenData.size(), ZMQ_SNDMORE);
zmq_send (wz->zsock, msgData.c_str(), msgData.size(), 0);
}
if (mStruct->counter==SLAVES_EXPECTED) {
sendCommand(wz,"Master connected to slaves.");
mStruct->synchronized = true;
}
}
}
bool MasterInterface::IDRegistered(masterStruct* mStruct, const std::string& id) {
for (int i=0; i < SLAVES_EXPECTED; i++) {
if (mStruct->slaveIDs[i]=="") continue;
if (mStruct->slaveIDs[i].compare(id)==0)
return true;
}
return false;
}
我在程序上运行valgrind,它报告3个块中的87个字节可能丢失,表明这是数据“可能丢失”的行。 std::string idenData = std::string(static_cast(iden), numIDBytes);
我不认为我在这里做错了什么,为什么 valgrind 抱怨?这是误报吗?
谢谢。
这是 mstruct。
struct masterStruct {
public:
int counter;
bool synchronized;
std::string slaveIDs[3];
};
编译时没有优化。 -O0
这是 valgrind 消息:
^C[Signal Caught] Closing connections...
Exited Master Process...
==6606==
==6606== HEAP SUMMARY:
==6606== in use at exit: 143 bytes in 4 blocks
==6606== total heap usage: 5,866 allocs, 5,862 frees, 533,480 bytes allocated
==6606==
==6606== Searching for pointers to 4 not-freed blocks
==6606== Checked 239,000 bytes
==6606==
==6606== 87 bytes in 3 blocks are possibly lost in loss record 2 of 2
==6606== at 0x4A074CC: operator new(unsigned long) (vg_replace_malloc.c:298)
==6606== by 0x3A7CC9C3C8: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13)
==6606== by 0x3A7CC9CDE4: ??? (in /usr/lib64/libstdc++.so.6.0.13)
==6606== by 0x3A7CC9CF6A: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, unsigned long, std::allocator<char> const&) (in /usr/lib64/libstdc++.so.6.0.13)
==6606== by 0x402FD5: MasterInterface::zsock_cb(ev_loop*, ev_zsock_t*, int) (MasterInterface.cpp:74)
==6606== by 0x404C6B: s_check_cb (ev_zsock.c:61)
==6606== by 0x4E872BC: ev_invoke_pending (ev.c:3155)
==6606== by 0x4E8BAE1: ev_run (ev.c:3555)
==6606== by 0x403423: MasterInterface::init() (MasterInterface.cpp:118)
==6606== by 0x4046DB: main (PXSMaster.cpp:29)
==6606==
==6606== LEAK SUMMARY:
==6606== definitely lost: 0 bytes in 0 blocks
==6606== indirectly lost: 0 bytes in 0 blocks
==6606== possibly lost: 87 bytes in 3 blocks
==6606== still reachable: 56 bytes in 1 blocks
==6606== suppressed: 0 bytes in 0 blocks
==6606== Reachable blocks (those to which a pointer was found) are not shown.
==6606== To see them, rerun with: --leak-check=full --show-reachable=yes
==6606==
==6606== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
--6606--
--6606-- used_suppression: 4 U1004-ARM-_dl_relocate_object
==6606==
==6606== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 4 from 4)
bash-4.1$
【问题讨论】:
-
为什么要将
iden或msg转换为char*?在那种情况下应该是隐含的。 -
如果没有看到
IDRegistered和mStruct->slaveIDs,很难分辨。如果我不得不猜测,我敢打赌你永远不会释放mStruct或mStruct->slaveIDs。 -
@CoffeeandCode 这只是我倾向于做的事情。它会影响 valgrind 的情况吗?
-
由于
slaveIDs中有 3 个元素,而 valgrind 报告了 3 个块,我几乎可以保证你没有释放mStruct。 -
如果是全局的,那取决于你如何退出程序。程序必须正常退出,这通常是通过调用
exit(不是_exit)或从main返回。如果它是本地的,那取决于包含它的堆栈帧是否曾经退出过。例如,如果您在包含本地的函数中调用exit,则不可能。