Need help with asio::ip::tcp::endpoint & ::socket constructors

Feb 18, 2021 at 9:38pm
Is it possible to declare and initialize asio::ip::tcp::endpoint and asio::ip::tcp::socket without using constructors?

For example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <asio.hpp>
#include <asio/ts/buffer.hpp>
#include <asio/ts/internet.hpp>

asio::ip::tcp::endpoint * pendpoint;
asio::ip::tcp::socket * psocket;

int main(){
    asio::error_code ec;
    asio::io_context context;
    pendpoint = (asio::ip::tcp::endpoint*) malloc (sizeof(asio::ip::tcp::endpoint));
    psocket = (asio::ip::tcp::socket*) malloc (sizeof(asio::ip::tcp::socket));

    //This is bad can't do constructor on pointer. How to fix?
    pendpoint(asio::ip::make_address(127.0.0.1, ec), 80);
    psocket(context);

    psocket->connect(pendpoint, ec);
    
    free(pendpoint);
    free(psocket);
    return 0;
}
Feb 18, 2021 at 11:25pm
Use placement new to start the lifetime of an endpoint object in provided storage.

After you're done with the object you should later call its destructor to formally end its lifetime. This is not strictly a requirement, but it's often important because destructors may return resources to the system. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <memory>
#include <type_traits>

#include <boost/asio.hpp>
#include <boost/asio/ts/buffer.hpp>
#include <boost/asio/ts/internet.hpp>

namespace asio = boost::asio;
namespace ip   = asio::ip;

template <typename T> using aligned_storage_for =
  std::aligned_storage_t<sizeof(T), alignof(T)>;

int main()
{
    boost::system::error_code ec;
    asio::io_context ctx;
    aligned_storage_for<ip::tcp::endpoint> buf_endpoint;
    aligned_storage_for<ip::tcp::socket>   buf_socket;

    auto pendpoint = reinterpret_cast<ip::tcp::endpoint*>(&buf_endpoint);
    auto psocket   = reinterpret_cast<ip::tcp::socket*>  (&buf_socket);

    // Start the lifetime of an endpoint in the storage pointed to by pendpoint
    // We have guaranteed that the pointed-to memory block is
    //   - large enough to store an endpoint object; and
    //   - suitably aligned for the endpoint object.
    // Next, do the same for the socket.
    new (pendpoint) ip::tcp::endpoint(asio::ip::make_address("127.0.0.1"), 80);
    new (psocket)   ip::tcp::socket(ctx);
    
    psocket->connect(*pendpoint, ec);

    // typical C idiom: clean up in reverse order of initialization
    // Ends the lifetime of the objects
    psocket->ip::tcp::socket::~socket();
    pendpoint->ip::tcp::endpoint::~endpoint();

    // If we dynamically allocated storage with malloc or new, this is the location 
    // to release it
}
Last edited on Feb 19, 2021 at 1:47am
Feb 19, 2021 at 12:42am
The second line on this code gives me error: 'aligned_storage_t' in namespace 'std' does not name a template type.
1
2
template <typename T> using aligned_storage_for =
std::aligned_storage_t<sizeof(T), alignof(T)>;
Feb 19, 2021 at 1:13am
1. I forgot to #include <type_traits>, sorry.
2. You must be using C++14 at least.
See:
https://en.cppreference.com/w/cpp/types/aligned_storage

Last edited on Feb 19, 2021 at 1:46am
Feb 19, 2021 at 2:19am
Thank you Mbozzi!
Topic archived. No new replies allowed.