【问题标题】:Valgrind complains data possibly lostValgrind 抱怨数据可能丢失
【发布时间】: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$ 

【问题讨论】:

  • 为什么要将idenmsg 转换为char*?在那种情况下应该是隐含的。
  • 如果没有看到IDRegisteredmStruct-&gt;slaveIDs,很难分辨。如果我不得不猜测,我敢打赌你永远不会释放mStructmStruct-&gt;slaveIDs
  • @CoffeeandCode 这只是我倾向于做的事情。它会影响 valgrind 的情况吗?
  • 由于 slaveIDs 中有 3 个元素,而 valgrind 报告了 3 个块,我几乎可以保证你没有释放 mStruct
  • 如果是全局的,那取决于你如何退出程序。程序必须正常退出,这通常是通过调用exit(不是_exit)或从main返回。如果它是本地的,那取决于包含它的堆栈帧是否曾经退出过。例如,如果您在包含本地的函数中调用exit,则不可能。

标签: c++ valgrind


【解决方案1】:

@Dark Falcon 是正确的。

MasterInterface 类被声明为全局变量。 在这堂课中,有

struct masterStruct masStruct; 

其中有3个std::string的数组。

这就是问题所在。当我按下 Ctrl-C 时,valgrind 可能没有考虑全局变量,因此这些字节可能会丢失。

将 MasterInterface 声明放在 main() 中解决了可能丢失的错误。

【讨论】:

    猜你喜欢
    • 2012-04-12
    • 2018-02-02
    • 2011-04-05
    • 1970-01-01
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多