C++ 函数返回时出现Cpp调试断言错误
我正在尝试实现一个boostwebsocket服务,它使用googleprotobuf格式来传输数据。我已经用.h和.cpp文件实现了一个非常简单的库,但在从cryptowatch_API.cpp退出connect()时(使用brakepoints进行检查)出现以下错误 调试断言失败 文件:debug_heap.cpp 电话号码:908 表达式:块类型是否有效(头->块使用) 最奇怪的是,代码每隔一段时间就会毫无问题地运行到最后。。。有人知道这里会出什么问题吗?我的文件发布在下面,我正在使用VS2019。任何帮助都将不胜感激!我已经为此挣扎了很长一段时间C++ 函数返回时出现Cpp调试断言错误,c++,C++,我正在尝试实现一个boostwebsocket服务,它使用googleprotobuf格式来传输数据。我已经用.h和.cpp文件实现了一个非常简单的库,但在从cryptowatch_API.cpp退出connect()时(使用brakepoints进行检查)出现以下错误 调试断言失败 文件:debug_heap.cpp 电话号码:908 表达式:块类型是否有效(头->块使用) 最奇怪的是,代码每隔一段时间就会毫无问题地运行到最后。。。有人知道这里会出什么问题吗?我的文件发布在下面,我正在使用VS
#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <cstdlib>
#include <iostream>
#include <string>
#include "public/stream/stream.pb.h"
#include "cryptowatch_API.h"
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
// Sends a WebSocket message and prints the response
int main()
{
GOOGLE_PROTOBUF_VERIFY_VERSION;
const char* API_key = "INSERT_API_KEY";
Cryptowatch_API cryptowatch_API(API_key);
ProtobufStream::AuthenticationResult::Status auth_status;
auth_status = cryptowatch_API.connect();
/*
if (auth_status == ProtobufStream::AuthenticationResult::AUTHENTICATED) {
std::cout << "Authentication successful" << std::endl;
}
else {
//std::cout << "Authentication failed: " << auth_status << std::endl;
}
*/
cryptowatch_API.disconnect();
return EXIT_SUCCESS;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“public/stream/stream.pb.h”
#包括“cryptowatch_API.h”
命名空间beast=boost::beast;//从…起
命名空间http=beast::http;//从…起
命名空间websocket=beast::websocket;//从…起
名称空间net=boost::asio;//从…起
名称空间ssl=boost::asio::ssl;//从…起
使用tcp=boost::asio::ip::tcp;//从…起
//发送WebSocket消息并打印响应
int main()
{
谷歌协议验证版本;
const char*API\u key=“插入API\u key”;
Cryptowatch_API Cryptowatch_API(API_密钥);
ProtobufStream::AuthenticationResult::Status auth_Status;
auth_status=cryptowatch_API.connect();
/*
if(auth_status==ProtobufStream::AuthenticationResult::AUTHENTICATED){
std::cout握手(主机、连接\u url\u添加);
//此缓冲区将保存传入消息
beast::flat_缓冲区;
ProtobufStream::StreamMessage StreamMessage;
//streamMessage.InitAsDefaultInstance();
while(streamMessage.has_authenticationresult()==FALSE){
buffer.clear();
如果(ws->read(buffer)>0){
//从websocket输入消息解析streamMessage
streamMessage.ParseFromArray(静态_转换(buffer.data().data()),buffer.data().size());
}
}
ProtobufStream::AuthenticationResult::Status authenticated;
authenticated=streamMessage.authenticationresult().status();
返回认证;
}
//取消对websocket对象的引用以将其存储在Cryptowatch_API中
——您正在存储一个局部变量的地址。一旦该函数返回,该地址就会烟消云散。当然,这也是一个必须修复的错误(感谢您将我指向它!)实际上是protobuf库把事情搞砸了。streamMessage.ParseFromArray(static_cast(buffer.data().data()),buffer.data().size());当buffer.data().size()仅为1时,它被销毁时出错。
// cryptowatch_API.h
#ifndef Cryptowatch_API_H // include guard
#define Cryptowatch_API_H
class Cryptowatch_API
{
private:
const char* API_key;
boost::beast::websocket::stream<boost::beast::ssl_stream<boost::asio::ip::tcp::socket>>* ws;
public:
Cryptowatch_API(const char*);
ProtobufStream::AuthenticationResult::Status connect();
void disconnect();
};
#endif Cryptowatch_API_H
// cryptowatch_API.cpp
#include <boost/beast/core.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/beast/websocket/ssl.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ssl/stream.hpp>
#include <cstdlib>
#include <iostream>
#include <string>
#include "public/stream/stream.pb.h"
#include "cryptowatch_API.h"
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
Cryptowatch_API::Cryptowatch_API(const char* API_key) {
Cryptowatch_API::API_key = API_key;
}
void Cryptowatch_API::disconnect() {
//ws->close(websocket::close_code::normal);
}
//Will return TRUE when connect was successful, FALSE when unsuccessful
ProtobufStream::AuthenticationResult::Status Cryptowatch_API::connect() {
// Check command line arguments.
auto const host = "stream.cryptowat.ch";
auto const port = "443";
// The io_context is required for all I/O
net::io_context ioc;
// The SSL context is required, and holds certificates
ssl::context ctx{ ssl::context::tlsv12_client };
// This holds the root certificate used for verification
//load_root_certificates(ctx);
// These objects perform our I/O
tcp::resolver resolver{ ioc };
websocket::stream<beast::ssl_stream<tcp::socket>> webs{ ioc, ctx };
//Dereference the websocket object to store it in Cryptowatch_API
ws = &webs;
// Look up the domain name
auto const results = resolver.resolve(host, port);
// Make the connection on the IP address we get from a lookup
net::connect(ws->next_layer().next_layer(), results.begin(), results.end());
// Perform the SSL handshake
ws->next_layer().handshake(ssl::stream_base::client);
// Set a decorator to change the User-Agent of the handshake
ws->set_option(websocket::stream_base::decorator(
[](websocket::request_type& req)
{
req.set(http::field::user_agent,
std::string(BOOST_BEAST_VERSION_STRING) +
" websocket-client-coro");
}));
// Perform the websocket handshake
std::string connect_url_addition = "/connect?format=binary&apikey=";
connect_url_addition.append(API_key);
ws->handshake(host, connect_url_addition);
// This buffer will hold the incoming message
beast::flat_buffer buffer;
ProtobufStream::StreamMessage streamMessage;
//streamMessage.InitAsDefaultInstance();
while (streamMessage.has_authenticationresult() == FALSE) {
buffer.clear();
if (ws->read(buffer) > 0) {
//Parse streamMessage from the websocket input message
streamMessage.ParseFromArray(static_cast<char const*>(buffer.data().data()), buffer.data().size());
}
}
ProtobufStream::AuthenticationResult::Status authenticated;
authenticated = streamMessage.authenticationresult().status();
return authenticated;
}