问题是:
<。>`。/ runTests'出错:free():无效指针: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;
}
编辑*:添加了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
为什么在测试运行并完成并且测试套件中的指针被创建和销毁时会发生这种情况?
答案 0 :(得分:1)
我敢打赌问题是这个初始化:
bw((unique_ptr<serial::BufferWrapper>) new serial::BufferWrapper())
这里你分配了一个serial::BufferWrapper
对象,但是你将指针转换为std::unique_ptr<...>
对象,这意味着编译器会调用std::unique_ptr<...>
运动 constructor。应该调用的构造函数应该是指向包装类型的指针。
因此,要解决问题,请跳过转换并执行
bw(new serial::BufferWrapper)
这里有什么教训?永远永远在C ++中使用C风格的转换。