On some low memory systems, calling malloc (by the use of strdup) may cause memory fragmentation, which eventually results in out of memory situations. Using the json_object_new_string_noalloc() function can be a help to solve such issues.pull/620/head
@@ -1158,6 +1158,14 @@ struct json_object *json_object_new_string_ext(const char *s, const int len, | |||||
dstbuf = jso->o.c_string.str.data; | dstbuf = jso->o.c_string.str.data; | ||||
memcpy(dstbuf, s, jso->o.c_string.len); | memcpy(dstbuf, s, jso->o.c_string.len); | ||||
dstbuf[len] = '\0'; | dstbuf[len] = '\0'; | ||||
if (flags & JSON_C_NEW_STRING_NO_STRDUP) | |||||
{ | |||||
/* a little hack to get rid of constness */ | |||||
memcpy(&dstbuf, &s, sizeof(char *)); | |||||
/* string buffer must be free'd here | |||||
to avoid memory leaks */ | |||||
free(dstbuf); | |||||
} | |||||
return jso; | return jso; | ||||
} | } | ||||
@@ -1172,6 +1180,9 @@ struct json_object *json_object_new_string_ext(const char *s, const int len, | |||||
dstbuf[len] = '\0'; | dstbuf[len] = '\0'; | ||||
} | } | ||||
} | } | ||||
else if (flags & JSON_C_NEW_STRING_NO_STRDUP) | |||||
/* a little hack to get rid of constness */ | |||||
memcpy(&dstbuf, &s, sizeof(char *)); | |||||
/* cannot be reached if o.c_string.str.data is used */ | /* cannot be reached if o.c_string.str.data is used */ | ||||
if (!dstbuf) | if (!dstbuf) | ||||
@@ -1195,6 +1206,11 @@ struct json_object *json_object_new_string_len(const char *s, const int len) | |||||
return json_object_new_string_ext(s, len, JSON_C_NEW_STRING_LENGTH); | return json_object_new_string_ext(s, len, JSON_C_NEW_STRING_LENGTH); | ||||
} | } | ||||
struct json_object *json_object_new_string_noalloc(const char *s) | |||||
{ | |||||
return json_object_new_string_ext(s, strlen(s), JSON_C_NEW_STRING_NO_STRDUP); | |||||
} | |||||
const char *json_object_get_string(struct json_object *jso) | const char *json_object_get_string(struct json_object *jso) | ||||
{ | { | ||||
if (!jso) | if (!jso) | ||||
@@ -54,6 +54,11 @@ extern "C" { | |||||
* memory is managed by the json_object. | * memory is managed by the json_object. | ||||
*/ | */ | ||||
#define JSON_C_NEW_STRING_LENGTH (1 << 1) | #define JSON_C_NEW_STRING_LENGTH (1 << 1) | ||||
/** | |||||
* No copy of the string is made, the given string buffer must be heap-allocated, | |||||
* and not be free'd, as its memory will be managed by the json_object then. | |||||
*/ | |||||
#define JSON_C_NEW_STRING_NO_STRDUP (1 << 2) | |||||
/** | /** | ||||
* A flag for the json_object_to_json_string_ext() and | * A flag for the json_object_to_json_string_ext() and | ||||
@@ -913,6 +918,21 @@ JSON_EXPORT struct json_object *json_object_new_string(const char *s); | |||||
*/ | */ | ||||
JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len); | JSON_EXPORT struct json_object *json_object_new_string_len(const char *s, const int len); | ||||
/** Create a new empty json_object of type json_type_string without allocating | |||||
* new memory. | |||||
* | |||||
* Create a new json_object of type json_type_string and use the given string | |||||
* buffer as is, without allocating new memory nor duplication. The ownership | |||||
* of the string buffer will be transferred to the newly created json_object. | |||||
* The buffer will be freed when the last instance of this object will be | |||||
* destroyed by calling json_object_put(). | |||||
* | |||||
* @param s the string buffer, must be heap alloacted and must not be freed. | |||||
* @returns a json_object of type json_type_string | |||||
* @see json_object_new_string_ext() | |||||
*/ | |||||
JSON_EXPORT struct json_object *json_object_new_string_noalloc(const char *s); | |||||
/** Get the string value of a json_object | /** Get the string value of a json_object | ||||
* | * | ||||
* If the passed object is of type json_type_null (i.e. obj == NULL), | * If the passed object is of type json_type_null (i.e. obj == NULL), | ||||