diff options
author | Philipp A. Hartmann <pah@qo.cx> | 2015-04-16 22:05:08 +0300 |
---|---|---|
committer | Philipp A. Hartmann <pah@qo.cx> | 2015-04-16 22:05:08 +0300 |
commit | 0c5c1538dcfc7f160e5a4aa208ddf092c787be5a (patch) | |
tree | 79bd73cd89f4c4b94cfbe125f499ee9fffa03d9a /include/rapidjson/document.h | |
parent | 94c0082e38c55b2acf8aa9848125d20692808d45 (diff) |
Avoid calling memcpy with NULL pointers
According to the C/C++ standards, calling `memcpy(NULL, NULL, 0)` is
undefined behaviour. Recent GCC versions may rely on this by optimizing
NULL pointer checks more aggressively, see [1].
This patch tries to avoid calling std::memcpy with zero elements.
As a side effect, explicitly return NULL when requesting an empty block
from MemoryPoolAllocator::Malloc.
This may be related to #301.
[1] https://gcc.gnu.org/gcc-4.9/porting_to.html
Diffstat (limited to 'include/rapidjson/document.h')
-rw-r--r-- | include/rapidjson/document.h | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/include/rapidjson/document.h b/include/rapidjson/document.h index 204e3bde..3aaef13b 100644 --- a/include/rapidjson/document.h +++ b/include/rapidjson/document.h @@ -1582,16 +1582,24 @@ private: // Initialize this value as array with initial data, without calling destructor.
void SetArrayRaw(GenericValue* values, SizeType count, Allocator& allocator) {
flags_ = kArrayFlag;
- data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
- std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
+ if (count) {
+ data_.a.elements = (GenericValue*)allocator.Malloc(count * sizeof(GenericValue));
+ std::memcpy(data_.a.elements, values, count * sizeof(GenericValue));
+ }
+ else
+ data_.a.elements = NULL;
data_.a.size = data_.a.capacity = count;
}
//! Initialize this value as object with initial data, without calling destructor.
void SetObjectRaw(Member* members, SizeType count, Allocator& allocator) {
flags_ = kObjectFlag;
- data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
- std::memcpy(data_.o.members, members, count * sizeof(Member));
+ if (count) {
+ data_.o.members = (Member*)allocator.Malloc(count * sizeof(Member));
+ std::memcpy(data_.o.members, members, count * sizeof(Member));
+ }
+ else
+ data_.o.members = NULL;
data_.o.size = data_.o.capacity = count;
}
|