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

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;
}
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
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)>;
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
Thank you Mbozzi!
Topic archived. No new replies allowed.