]> git.seodisparate.com - UDPConnection/commitdiff
Add UDPC_free_PacketInfo_ptr(...)
authorStephen Seo <seo.disparate@gmail.com>
Wed, 19 Apr 2023 09:26:45 +0000 (18:26 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Wed, 19 Apr 2023 09:50:26 +0000 (18:50 +0900)
Also add unit test for this function.

src/UDPC.h
src/UDPConnection.cpp
src/test/TestUDPC.cpp

index 06b995f1945a44cbc99afc63c523b7e614cb17eb..25026dea7658018d315db99f253350679fa55dc2 100644 (file)
@@ -161,8 +161,9 @@ typedef struct UDPC_EXPORT UDPC_ConnectionId {
  *
  * If \ref data is NULL or \ref dataSize is 0, then this packet is invalid.
  *
- * \warning This struct must be free'd with a call to UDPC_free_PacketInfo to
- * avoid a memory leak.
+ * \warning This struct must be free'd with a call to
+ * \ref UDPC_free_PacketInfo_ptr or \ref UDPC_free_PacketInfo to avoid a memory
+ * leak.
  */
 typedef struct UDPC_EXPORT UDPC_PacketInfo {
     /*!
@@ -657,19 +658,37 @@ UDPC_EXPORT UDPC_Event UDPC_get_event(UDPC_HContext ctx, unsigned long *remainin
  * \brief Get a received packet from a given UDPC context.
  *
  * \warning The received packet (if valid) must be free'd with a call to
- * \ref UDPC_free_PacketInfo() to avoid a memory leak.
+ * \ref UDPC_free_PacketInfo_ptr or \ref UDPC_free_PacketInfo to avoid a memory
+ * leak.
  */
 UDPC_EXPORT UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned long *remaining);
 
 /*!
  * \brief Frees a UDPC_PacketInfo.
  *
- * Internally, the member variable \ref UDPC_PacketInfo::data will be free'd and
- * set to NULL and \ref UDPC_PacketInfo::dataSize will be set to 0 if the given
- * packet is valid.
+ * Internally, the member variable \ref UDPC_PacketInfo::data will be free'd.
+ * \ref UDPC_free_PacketInfo_ptr is safer to use than this function, as it
+ * also zeros out the relevant data to avoid double frees.
  */
 UDPC_EXPORT void UDPC_free_PacketInfo(UDPC_PacketInfo pInfo);
 
+/*!
+ * \brief Frees a UDPC_PacketInfo.
+ *
+ * This is a safer alternative to \ref UDPC_free_PacketInfo because it
+ * internally zeroes out the internal pointer and size variables, making it
+ * safe to pass the same ptr multiple times to this function as it avoids a
+ * double free.
+ *
+ * Usage:
+ * \code{.c}
+ * UDPC_PacketInfo pinfo = UDPC_get_received(ctx, NULL);
+ * UDPC_free_PacketInfo_ptr(&pinfo);
+ * UDPC_free_PacketInfo_ptr(&pinfo); // This is safe, no double free.
+ * \endcode
+ */
+UDPC_EXPORT void UDPC_free_PacketInfo_ptr(UDPC_PacketInfo *pInfoPtr);
+
 /*!
  * \brief Sets public/private keys used for packet verification
  *
index d4204009e3ef766cfe8a1a7eceeb7954ea1df41d..b8b0f22deef4dc600a6db6fc46eca3ef2f90da95 100644 (file)
@@ -2496,8 +2496,14 @@ UDPC_PacketInfo UDPC_get_received(UDPC_HContext ctx, unsigned long *remaining) {
 void UDPC_free_PacketInfo(UDPC_PacketInfo pInfo) {
     if(pInfo.data && pInfo.dataSize > 0) {
         std::free(pInfo.data);
-        pInfo.data = 0;
-        pInfo.dataSize = 0;
+    }
+}
+
+void UDPC_free_PacketInfo_ptr(UDPC_PacketInfo *pInfoPtr) {
+    if (pInfoPtr->data && pInfoPtr->dataSize > 0) {
+        std::free(pInfoPtr->data);
+        pInfoPtr->data = nullptr;
+        pInfoPtr->dataSize = 0;
     }
 }
 
index e0e0f7669c95a3503c6f9089d4d04b64a9e2439e..75ba9766c803b6340acc8caad2cd1d7d4de72c70 100644 (file)
@@ -4,6 +4,7 @@
 #include <UDPC_Defines.hpp>
 
 #include <cstdio>
+#include <cstdlib>
 #include <cstring>
 #include <future>
 
@@ -328,3 +329,12 @@ TEST(UDPC, a4toa6) {
     a4 = htonl(0x01020304);
     EXPECT_EQ(UDPC_a4toa6(a4), a6);
 }
+
+TEST(UDPC, free_packet_ptr) {
+    UDPC_PacketInfo pinfo;
+    pinfo.dataSize = 8;
+    pinfo.data = (char*)std::malloc(pinfo.dataSize);
+
+    UDPC_free_PacketInfo_ptr(&pinfo);
+    UDPC_free_PacketInfo_ptr(&pinfo);
+}