gpt4 book ai didi

c++ - 运行 GTest 时指针无效

转载 作者:行者123 更新时间:2023-11-28 05:41:28 26 4
gpt4 key购买 nike

问题是:

Error in `./runTests': free(): invalid pointer: 0x00007fdb92fe27a0 Aborted

测试套件是:

#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();
}

函数校验和是:

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;
}

编辑* 添加声明:

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

为什么当测试运行并完成并且创建和销毁测试套件中的指针时会发生这种情况?

最佳答案

我敢打赌问题出在这个初始化上:

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

这里你分配一个serial::BufferWrapper对象,然后将指针指向 std::unique_ptr<...> object,这意味着编译器将调用 std::unique_ptr<...> 运动 constructor .应调用的构造函数应该是采用指向包装类型的指针的构造函数。

所以要解决这个问题,只需跳过转换并执行

bw(new serial::BufferWrapper)

这里的教训?永远不要永远在 C++ 中使用 C 风格的转换。

关于c++ - 运行 GTest 时指针无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37003246/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com