2016-05-03 10 views
0

問題がある実行している: `./runTests'で無効なポインタGTEST

エラー:無料():無効なポインタ:0x00007fdb92fe27a0

異常終了テストスイートは次のとおりです。

#include "serial/BufferWrapper.h" 
#include <iostream> 
#include <memory> 
#include <gtest/gtest.h> 


#define STREAM_LEN 128 

using namespace std; 

namespace { 

// The fixture for testing class BufferWrapperTest. 
class BufferWrapperTest : public ::testing::Test 
{ 
public: 
    // Objects declared here can be used by all tests. 
    unique_ptr<serial::BufferWrapper> bw; 

    BufferWrapperTest() : 
     bw((unique_ptr<serial::BufferWrapper>) new serial::BufferWrapper()) 
    {} 

    //virtual ~BufferWrapperTest(){} 

    // If the constructor and destructor are not enough for setting up 
    // and cleaning up each test, you can define the following methods: 

    //virtual void SetUp() { 
     // Code here will be called immediately after the constructor (right 
     // before each test). 
    //} 

    //virtual void TearDown() { 
     // Code here will be called immediately after each test (right 
     // before the destructor). 
    //} 

}; // BufferWrapperTest 

/*! tests that checksum works in buffer wrapper */ 
TEST_F(BufferWrapperTest, CheckSum) { 

    std::vector<unsigned char> test_vec; 

    test_vec.push_back('0');  // us1 
    test_vec.push_back('0');  // us2 
    test_vec.push_back('0');  // ir1 
    test_vec.push_back('0');  // ir2 
    test_vec.push_back('0');  // ir3 
    test_vec.push_back('0');  // wheel 
    test_vec.push_back('0');  // dis1 
    test_vec.push_back('0');  // dis2 
    test_vec.push_back('0');  // dis3 
    test_vec.push_back('0');  // dis4 
    test_vec.push_back('0');  // light 

    ASSERT_EQ((unsigned char) 48, bw->checksum(test_vec)); 

    // clear after first test 
    test_vec.clear(); 

    test_vec.push_back('2');  // us1 
    test_vec.push_back('3');  // us2 
    test_vec.push_back('4');  // ir1 
    test_vec.push_back('5');  // ir2 
    test_vec.push_back('6');  // ir3 
    test_vec.push_back('0');  // wheel 
    test_vec.push_back('0');  // dis1 
    test_vec.push_back('0');  // dis2 
    test_vec.push_back('0');  // dis3 
    test_vec.push_back('0');  // dis4 
    test_vec.push_back('0');  // light 

    ASSERT_EQ((unsigned char) 54, bw->checksum(test_vec)); 
} 

int main(int argc, char **argv) { 
    ::testing::InitGoogleTest(&argc, argv); 
    return RUN_ALL_TESTS(); 
} 

機能checksumは:

unsigned char serial::BufferWrapper::checksum(const std::vector<unsigned char> pkt) 
{ 
    unsigned char chksum = 0; 
    if (pkt.size() == 0) return chksum; 
    for (auto it = pkt.begin(); it != pkt.end(); ++it) { 
     // the checksum is calculated by XOR all elements 
     chksum = (unsigned char)(chksum^*it); 
    } 
    return chksum; 
} 

EDIT *:追加されましたserial::BufferWrapper

#include <iostream> 
#include <iomanip> 
#include <mutex> 
#include <algorithm> 
#include "serial/BufferWrapper.h" 
#include "containerfactory/SBDContainer.h" 

using namespace std; 

// append receive buffer mutex 
std::mutex arb; 
// append send buffer mutex 
std::mutex asb; 
// read send buffer mutex 
std::mutex rsm; 
// read receive buffer mutex 
std::mutex rrm; 

/*! constructor */ 
serial::BufferWrapper::BufferWrapper() : buffer_in({}), buffer_out({}) 
{ 
    cout << "creating buffer wrapper... "; 
    cout << "[OK]" << endl; 
} 


/*! destructor */ 
serial::BufferWrapper::~BufferWrapper() 
{ 
    cout << "destroying buffer wrapper... "; 
    cout << "[OK]" << endl; 
} 


/*! appends a correct packet to the receive buffer */ 
void serial::BufferWrapper::appendReceiveBuffer(vector<unsigned char> data) 
{ 
    // lock mutex 
    arb.lock(); 
    // return if the length of the vedcor is too short 
    if (data.size() < SBDPKTSIZE) { 
     // unlock mutex 
     arb.unlock(); 
     return; 
    } 
    // the vector to hold the correct packet 
    vector<unsigned char> valid_pkt; 
    // loop through the received data from the read and look 
    // for a correct packet 
    for (auto it = data.begin(); it != data.end(); it++) { 
     if (it + SBDPKTSIZE > data.end()) { 
      break; 
     } 
     if (*it == DEL_ONE && *(it+DEL_TWO_POS) == DEL_TWO && 
       *(it+DEL_DBCOLON_POS) == DEL_DBCOLON && *(it+DEL_COMMA_POS) == DEL_COMMA) { 
      unsigned char us1 = *(it+US1_POS); 
      //printf("US1:%i ", us1); 
      unsigned char us2 = *(it+US2_POS); 
      //printf("US2:%i ", us2); 
      unsigned char ir1 = *(it+IR1_POS); 
      //printf("IR1:%i ", ir1); 
      unsigned char ir2 = *(it+IR2_POS); 
      //printf("IR2:%i ", ir2); 
      unsigned char ir3 = *(it+IR3_POS); 
      //printf("IR3:%i ", ir3); 
      unsigned char wheel = *(it+WHL_POS); 
      //printf("WHEEL:%i ", wheel); 
      unsigned char dis1 = *(it+DIS_POS_1); 
      //printf("DIS1:%i ", dis1); 
      unsigned char dis2 = *(it+DIS_POS_2); 
      //printf("DIS2:%i ", dis2); 
      unsigned char dis3 = *(it+DIS_POS_3); 
      //printf("DIS3:%i ", dis3); 
      unsigned char dis4 = *(it+DIS_POS_4); 
      //printf("DIS4:%i ", dis4); 
      unsigned char light = *(it+LIGHT_SEN); 
      //printf("LIGHT:%i ", light); 
      unsigned char check = *(it+CHK_SUM); 
      //printf("CHECK:%i\n", check); 
      // fill the vector 
      valid_pkt = {us1, us2, ir1, ir2, ir3, wheel, dis1, dis2, dis3, dis4, light}; 
      // check if correct checksum 
      if (check == checksum(valid_pkt)) { 
       cout << "checksum OK" << endl; 
       break; 
      } 
      else { 
       cout << "checksum FAIL" << endl; 
       // clear the return vector 
       valid_pkt.clear(); 
       // find where next packet starts 
       it = find(it+1, data.end(), DEL_ONE); 
       // if not found, break 
       if (it == data.end()) break; 
      } 
     } 
    } 
    // push in front of the buffer if valid data 
    if (valid_pkt.size() != 0) { 
     buffer_in.push_front(valid_pkt); 
    } 
    // unlock mutex 
    arb.unlock(); 
} 


/*! returns the most recent valid packet from the read buffer */ 
vector<unsigned char> serial::BufferWrapper::readReceiveBuffer(void) 
{ 
    rrm.lock(); 
    // check for size, i.e. not empty 
    if(buffer_in.size() != 0) 
    { 
     // get 3the most recent packet, always in first position 
     std::vector<unsigned char> vec = buffer_in.at(0); 
     // clear the buffer 
     buffer_in.clear(); 
     rrm.unlock(); 
     return vec; 
    } 
    else 
    { 
     rrm.unlock(); 
     return {}; 
    } 
} 


/*! appends a correct packet to the send buffer */ 
void serial::BufferWrapper::appendSendBuffer(vector<unsigned char> vec) 
{ 
    // lock mutex 
    asb.lock(); 
    buffer_out.push_front(vec); 
    // and unlock after append 
    asb.unlock(); 
} 


/*! returns the most recent valid packet from the send buffer */ 
vector<unsigned char> serial::BufferWrapper::readSendBuffer(void) 
{ 
    rsm.lock(); 
    // check for size, i.e. not empty 
    if(buffer_out.size() != 0) 
    { 
     // get the most recent packet, always in first position 
     vector<unsigned char> v = buffer_out.at(0); 
     // clear the buffer 
     buffer_out.clear(); 
     rsm.unlock(); 
     return v; 
    } 
    else 
    { 
     rsm.unlock(); 
     return {}; 
    } 
} 


/*! calculates and returns the checksum for a valid packet */ 
unsigned char serial::BufferWrapper::checksum(const std::vector<unsigned char> pkt) 
{ 
    unsigned char chksum = 0; 
    if (pkt.size() == 0) return chksum; 
    for (auto it = pkt.begin(); it != pkt.end(); ++it) { 
     // the checksum is calculated by XOR all elements 
     chksum = (unsigned char)(chksum^*it); 
    } 
    return chksum; 
} 

EDIT *が宣言を追加しました:

namespace serial 
{ 
    class BufferWrapper 
    { 
    public: 
     /*! constructor */ 
     BufferWrapper(); 
     /*! destructor */ 
     ~BufferWrapper(); 
     /*! appends data read from the serial to the receive buffer */ 
     void appendReceiveBuffer(std::vector<unsigned char>); 
     /*! returns a valid packet from the receive buffer */ 
     std::vector<unsigned char> readReceiveBuffer(void); 
     /*! appends to the send buffer data to write to the serial */ 
     void appendSendBuffer(std::vector<unsigned char>); 
     /*! returns a valid packet to write to the serial */ 
     std::vector<unsigned char> readSendBuffer(void); 
     /*! returns the checksum for a valid packet */ 
     unsigned char checksum(const std::vector<unsigned char>); 
    private: 
     /*! the receive buffer */ 
     std::deque<std::vector<unsigned char>> buffer_in; 
     /*! the send buffer */ 
     std::deque<std::vector<unsigned char>> buffer_out; 
    }; 
} 

テストを実行しているから、完全なプリントアウトは、次のとおりです。

[==========] Running 1 test from 1 test case. 
[----------] Global test environment set-up. 
[----------] 1 test from BufferWrapperTest 
[ RUN  ] BufferWrapperTest.CheckSum 
creating buffer wrapper... [OK] 
destroying buffer wrapper... [OK] 
[  OK ] BufferWrapperTest.CheckSum (1 ms) 
[----------] 1 test from BufferWrapperTest (1 ms total) 

[----------] Global test environment tear-down 
[==========] 1 test from 1 test case ran. (1 ms total) 
[ PASSED ] 1 test. 
*** Error in `./runTests': free(): invalid pointer: 0x00007fdb92fe27a0 *** 
Aborted 

ですが、なぜでしょうテストが完了し、テストスイート内のポインタが作成され、破棄されますか?

+1

どのプラットフォーム/ OSですか? valgrindを使用しますか? serial :: BufferWrapperはどのように見えますか? – paulm

+0

OSはLinux Mintです。 'serial :: BufferWrapper'を追加しました。 – tik

+0

**テストスイート全体が実行された後、**エラーが発生します。 gdbでテスト実行ファイルを実行して、呼び出しスタックの様子を見てください。 –

答えて

1

私はこの問題は、この初期化であることを賭けるだろう。ここでは

bw((unique_ptr<serial::BufferWrapper>) new serial::BufferWrapper()) 

あなたは1つのserial::BufferWrapperオブジェクトを割り当てるが、その後、あなたはコンパイラがstd::unique_ptr<...>を呼び出しますstd::unique_ptr<...>オブジェクト、へのポインタをキャスト動きconstructor。呼び出されるコンストラクタは、ラップされた型へのポインタを取るコンストラクタである必要があります。だからキャスティングをスキップし、

bw(new serial::BufferWrapper) 

にここにレッスンを行い、問題を解決する

?決してには、C++でのCスタイルのキャストを使用しないでください。

+0

動作しませんでした。それでも同じエラー。 – tik

関連する問題