如何使用shared_ptr确保指针的存在
How to ensure pointer existence with shared_ptr?
我正在尝试使用Boost::asio
运行程序。这里有一个我用来做async_write()
:的方法
template<typename T>
void Write(shared_ptr<std::vector<T>> data){
std::cout << "Write Method [std::vector]" << std::endl;
ioService.post(boost::bind(&TCPClient::DoWrite<T>, this, data));
}
然后,调用DoWrite()
方法来实际发送矢量中的数据:
template<typename T>
void DoWrite(shared_ptr<std::vector<T>> data){
std::cout << "DoWrite Method [std::vector]" << std::endl;
boost::asio::async_write( socket_,
boost::asio::buffer(*data),
boost::bind(&TCPClient::handle_write,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
std::cout << "async_write executed" << std::endl;
}
但在运行时,我得到了这个错误:
程序:C:\Windows\SYSTEM32\MSVCP120D.dll文件:C:\Program Files(x86)\Microsoft Visual Studio 12.0\VC\include\vector Line:72
表达式:矢量迭代器不可解引用
经过调查,我知道问题是传递给方法的std::vector<T>
没有保持足够的活力,并且当写入发生时(因为它是异步的),矢量不存在,所以我得到了这个错误。
我知道问题是这样的,因为如果我删除template
,我的函数现在类似于:
void DoWrite(std::vector<char> data){
std::cout << "DoWrite Method [std::vector]" << std::endl;
backupVector = data;
boost::asio::async_write( socket_,
boost::asio::buffer(backupVector),
boost::bind(&TCPClient::handle_write,
this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)
);
std::cout << "async_write executed" << std::endl;
}
其中backupVector
是类内的std::vector<char>
,我没有得到错误,因为我有一个存在的引用,但我不能在运行时创建std::vector<T>
来存储类中的传入向量(我是对的吗?我是C++的新手)。所以我读了关于shared_ptr
:的文章
std::shared_ptr是一个智能指针,它保留对象。几个shared_ptr对象可能拥有相同的对象当出现以下情况之一时,对象将被销毁并释放其内存发生以下情况之一:
拥有该对象的最后一个剩余shared_ptr被销毁。
通过运算符=或reset()为拥有该对象的最后一个剩余shared_ptr分配另一个指针。
那么,如果我将指针传递给async_write
,如果对象有对它的引用,为什么它会被"销毁"?有其他方法吗?
这就是我如何使用Write()
方法:
std::vector<char> data;
data.push_back('B');
data.push_back(bValue);
client.Write<char>(make_shared<std::vector<char>>(data));
Sleep(100000);
我还远远不能告诉应该在这里做什么(缺少信息,只使用了几次asio),但从这个例子中推测,你应该能够使用类似于的自定义缓冲区类来传递缓冲区
// based on http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp11/buffers/reference_counted.cpp
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
template<class T>
class shared_const_buffer
{
public:
// Construct from a `shared_ptr`
explicit shared_const_buffer(std::shared_ptr<std::vector<T>> const& p_data)
: data_(p_data),
buffer_(boost::asio::buffer(*data_))
{}
// Implement the ConstBufferSequence requirements.
using value_type = boost::asio::const_buffer;
using const_iterator = boost::asio::const_buffer const*;
boost::asio::const_buffer const* begin() const { return &buffer_; }
boost::asio::const_buffer const* end() const { return &buffer_ + 1; }
private:
std::shared_ptr<std::vector<T>> data_;
boost::asio::const_buffer buffer_;
};
正如我对这个问题的评论中所提到的,我不知道传递用于发送(写入)的共享缓冲区是否是个好主意。
这是如何工作的:
在写函数中,您传入一个缓冲区:
boost::asio::async_write( socket_,
boost::asio::buffer(backupVector), /*...*/ );
在本例中,缓冲区是通过boost::asio::buffer
函数创建的。但是这个函数并不获取(也不共享)参数的所有权,它只存储一个引用/指针。传递的缓冲区对象被复制到套接字(在作业队列中)中,在作业完成之前,它一直存在于套接字中。
通过使用shared_const_buffer
而不是boost::asio::buffer
创建的缓冲对象,我们将向量的生存期扩展到至少创建的shared_const_buffer
对象的生存期。因此,向量至少会一直存在到作业完成为止。
请参阅async_write
的文档和buffer
功能/缓冲区无效的文档。
对shared_ptr的引用仅在执行Clint.write(…).时有效
如果你在这个参数之外声明它,它将活得更长,你的程序可能会工作。
您只需要确保它停留的时间足够长,以便由boost::asio调用的函数异步编写。
- 使用指针在存在特征库的情况下动态分配 c++ 中的矩阵
- 构造函数 (C++) 中的 char 指针参数存在问题
- C++为什么我的指针选择排序中存在分段错误?
- 迭代时将指向differents类型的指针保存在std::向量中
- 如果模板中存在成员函数指针,如何获取该指针
- 指向类成员函数的指针中存在类型转换错误
- 一个对象的两个指针.删除了一个指针,对象仍然存在
- 是否存在将长整型转换为指针有效的情况
- C ++如何创建一个即使对象被覆盖也会持续存在的指针?
- 指向派生作品的基本指针,即使派生对象不存在
- 这个危险指针示例是否因为 ABA 问题而存在缺陷?
- 指向可能不存在的对象的指针向量
- 如果存在任何循环关系,我应该假设弱指针使用吗?
- 带有功能指针的Typedef:函数不存在
- 即使在返回值之前释放后,数据仍在指针中仍然存在
- C++尝试删除不存在的指针
- 如何使用shared_ptr确保指针的存在
- 构造函数中指针到指针的默认值存在问题
- 指向类的指针存在问题
- 时间指针存在吗?