diff --git a/c/opendht.cpp b/c/opendht.cpp
index 1c8f2e12db26542f4dcaf26e19eb183917e6acdc..a6de6b9769a63bcb47b54c969bc6a6d0e479a856 100644
--- a/c/opendht.cpp
+++ b/c/opendht.cpp
@@ -504,14 +504,8 @@ struct sockaddr** dht_runner_get_public_address(const dht_runner* r) {
     if (addrs.empty())
         return nullptr;
     auto ret = (struct sockaddr**)malloc(sizeof(struct sockaddr*) * (addrs.size() + 1));
-    for (size_t i=0; i<addrs.size(); i++) {
-        if (const auto& addr = addrs[i]) {
-            ret[i] = (struct sockaddr*)malloc(addr.getLength());
-            memcpy((struct sockaddr*)ret[i], addr.get(), addr.getLength());
-        } else {
-            ret[i] = nullptr;
-        }
-    }
+    for (size_t i=0; i<addrs.size(); i++)
+        ret[i] = addrs[i].release();
     ret[addrs.size()] = nullptr;
     return ret;
 }
diff --git a/include/opendht/sockaddr.h b/include/opendht/sockaddr.h
index 2e3229bcd57640faa8c628af56880501d1559737..717515cd196487e9a25c7c5ecf8d6f5dc6c0ee1c 100644
--- a/include/opendht/sockaddr.h
+++ b/include/opendht/sockaddr.h
@@ -236,6 +236,15 @@ public:
         return *reinterpret_cast<sockaddr_in6*>(get());
     }
 
+    /** 
+     * Releases the ownership of the managed object, if any.
+     * The caller is responsible for deleting the object with free().
+     */
+    inline sockaddr* release() {
+        len = 0;
+        return addr.release();
+    }
+
     /**
      * Return true if address is a loopback IP address.
      */