У меня есть ошибка сегментации в следующем коде (на _answers.push_back(tmp);
).std :: vector segv из-за невероятного повреждения
Gdb сказал
(gdb) p tmp
$7 = "HTTP/1.0 200 OK\r\nContent-Type: text/plain; charset=UTF-8\r\nSet-Cookie: color=black;path=/\r\nSet-Cookie: code=f69a2d941420d23be97bbb1ae963295647a91c4f3faf9c5fa80727399927d9d5;path=/\r\nSet-Cookie: game=c1e"...
(gdb) call _answers.size()
$8 = 271275648142580811
Так что я предполагаю, что массив был поврежден. Но я не знаю, где это произошло.
// Network.hpp
#pragma once
#include <utility>
#include <string>
#include <vector>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
class Network
{
public:
Network(std::string const &, std::string const &);
~Network() {};
void init();
void connect();
void update();
void sendQuery(const std::string);
bool isConnected();
void reset();
std::string getAnswer();
void handleRead(const boost::system::error_code &, size_t);
void handleWrite(const boost::system::error_code &);
boost::asio::io_service _io_service;
private:
boost::asio::ip::tcp::resolver _resolver;
boost::asio::ip::tcp::socket _sock;
boost::asio::ip::tcp::resolver::iterator _it;
char _buff[2048];
std::vector<std::string> _answers;
std::string const &_host;
std::string const &_port;
bool _answered;
};
// Network.cpp
Network::Network(std::string const &host, std::string const &port) : _resolver(_io_service), _sock(_io_service), _host(host), _port(port), _answered(true) {}
void Network::connect() {
_answers.reserve(2048);
boost::asio::ip::tcp::resolver::query query(_host, _port);
boost::asio::ip::tcp::resolver::iterator iterator = _resolver.resolve(query);
boost::asio::connect(_sock.lowest_layer(), iterator);
}
void Network::handleRead(const boost::system::error_code &err, size_t bread) {
_answered = true;
if (err && err.value() != 2)
throw Gomoku::NetworkException(err.message());
if (bread > 0) {
std::string tmp(_buff);
_answers.push_back(tmp);
}
memset(_buff, 0, 2048);
}
void Network::handleWrite(const boost::system::error_code &err) {
if (err)
throw Gomoku::NetworkException(err.message());
}
void Network::reset() {
_io_service.poll();
_io_service.reset();
_answers.clear();
_answered = true;
}
void Network::sendQuery(const std::string req) {
_io_service.poll();
_io_service.reset();
if (_answered == 0)
return;
_answered = false;
connect();
const char *str = new char[req.length()];
str = req.c_str();
boost::asio::async_write(_sock, boost::asio::buffer(str, req.length()), boost::bind(&Network::handleWrite, this, boost::asio::placeholders::error));
boost::asio::async_read(_sock, boost::asio::buffer(_buff, 2048), boost::bind(&Network::handleRead, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
std::string Network::getAnswer() {
if (_answers.empty())
return "";
std::string tmp = _answers.back();
_answers.pop_back();
return tmp;
}
// Player.cpp
Player::Player(std::string const &host, std::string const &port) : _network(host, port) {
_myTurn = false;
_whiteScore = _blackScore = 0;
_host = host + ":" + port;
initMap();
}
void Player::connect() {
std::string str = "GET /players/connect/ HTTP/1.0\r\nHost: " + _host + "\r\nAccept: */*\r\n\r\n";
_network.sendQuery(str);
}
void Player::sendClick(std::pair<int, int> click, std::string const &header) {
std::stringstream ss;
ss << "POST /game/play/" << click.first << "/" << click.second << header << _cookie << "\r\n\r\n";
std::string req = ss.str();
_network.sendQuery(req);
_network._io_service.run();
_network._io_service.reset();
std::string ans = _network.getAnswer();
parseAnswer(ans);
req = "GET /game/map.txt" + header + _cookie + "\r\n\r\n";
_network.sendQuery(req);
}
Я также видел следующий код, следуя SEGV след (basic_string.h: 400):
: _M_dataplus(_M_local_data(), __str._M_get_allocator()) // TODO A traits
Ваша ошибка может иметь отношение к 'std :: string tmp (_buff); _answers.push_back (tmp); ', но удобно, вы не показали нам, как эта переменная была объявлена или инициализирована. Пожалуйста, укажите полный, минимальный, компилируемый пример, который показывает эту ошибку. –
'const char * str = new char [req.length()]; str = req.c_str(); 'Это утечка памяти. Кроме того, 'req' является параметром by-value, поэтому в основном является локальной переменной. Он выходит из сферы действия сразу после возвращения этой функции. – PaulMcKenzie
Полный минимальный пример: я беру 4 файла. Но в любом случае _buff является допустимым символом [2048] с его \ 0 в конце и обрабатывается только '' 'boost :: asio :: async_read (_sock, boost :: asio :: buffer (_buff, 2048) , boost :: bind (& Network :: handleRead, this, boost :: asio :: placeholders :: error, boost :: asio :: placeholders :: bytes_transferred)); '' ' То же самое для _answers, ведьма - это простой std :: vector, обрабатывается только в этом файле. все переменные с «_XXX» - это переменные экземпляра, объявленные в заголовке –
Arthur