浏览代码

ensure: use realloc if possible

Max Bruckner 8 年之前
父节点
当前提交
4fff92140e
共有 1 个文件被更改,包括 40 次插入13 次删除
  1. 40 13
      cJSON.c

+ 40 - 13
cJSON.c

@@ -81,6 +81,7 @@ static int cJSON_strcasecmp(const unsigned char *s1, const unsigned char *s2)
 
 static void *(*cJSON_malloc)(size_t sz) = malloc;
 static void (*cJSON_free)(void *ptr) = free;
+static void *(*cJSON_realloc)(void *pointer, size_t size) = realloc;
 
 static unsigned char* cJSON_strdup(const unsigned char* str)
 {
@@ -104,16 +105,33 @@ static unsigned char* cJSON_strdup(const unsigned char* str)
 
 void cJSON_InitHooks(cJSON_Hooks* hooks)
 {
-    if (!hooks)
+    if (hooks == NULL)
     {
         /* Reset hooks */
         cJSON_malloc = malloc;
         cJSON_free = free;
+        cJSON_realloc = realloc;
         return;
     }
 
-    cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc;
-    cJSON_free = (hooks->free_fn) ? hooks->free_fn : free;
+    cJSON_malloc = malloc;
+    if (hooks->malloc_fn != NULL)
+    {
+        cJSON_malloc = hooks->malloc_fn;
+    }
+
+    cJSON_free = free;
+    if (hooks->free_fn != NULL)
+    {
+        cJSON_free = hooks->free_fn;
+    }
+
+    /* use realloc only if both free and malloc are used */
+    cJSON_realloc = NULL;
+    if ((cJSON_malloc == malloc) && (cJSON_free == free))
+    {
+        cJSON_realloc = realloc;
+    }
 }
 
 /* Internal constructor. */
@@ -263,20 +281,29 @@ static unsigned char* ensure(printbuffer *p, size_t needed)
         }
     }
 
-    newbuffer = (unsigned char*)cJSON_malloc(newsize);
-    if (!newbuffer)
+    if (cJSON_realloc != NULL)
     {
-        cJSON_free(p->buffer);
-        p->length = 0;
-        p->buffer = NULL;
-
-        return NULL;
+        /* reallocate with realloc if available */
+        newbuffer = (unsigned char*)cJSON_realloc(p->buffer, newsize);
     }
-    if (newbuffer)
+    else
     {
-        memcpy(newbuffer, p->buffer, p->length);
+        /* otherwise reallocate manually */
+        newbuffer = (unsigned char*)cJSON_malloc(newsize);
+        if (!newbuffer)
+        {
+            cJSON_free(p->buffer);
+            p->length = 0;
+            p->buffer = NULL;
+
+            return NULL;
+        }
+        if (newbuffer)
+        {
+            memcpy(newbuffer, p->buffer, p->length);
+        }
+        cJSON_free(p->buffer);
     }
-    cJSON_free(p->buffer);
     p->length = newsize;
     p->buffer = newbuffer;