diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index ae8115a337e..149483e719f 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -110,6 +110,16 @@ extern "C" { #endif ; + /** + * A variant of realloc which zeros new bytes + */ + void *MEM_recallocN(void *vmemh, size_t len) +#if MEM_GNU_ATTRIBUTES + __attribute__((warn_unused_result)) + __attribute__((alloc_size(2))) +#endif + ; + /** * Allocate a block of memory of size len, with tag name str. The * memory is cleared. The name must be static, because only a diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index c4902e6aa5a..df6f4d59c7f 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -302,10 +302,45 @@ void *MEM_reallocN(void *vmemh, size_t len) newp = MEM_mallocN(len, memh->name); if (newp) { - if (len < memh->len) + if (len < memh->len) { + /* shrink */ memcpy(newp, vmemh, len); - else + } + else { + /* grow (or remain same size) */ memcpy(newp, vmemh, memh->len); + } + } + + MEM_freeN(vmemh); + } + + return newp; +} + +void *MEM_recallocN(void *vmemh, size_t len) +{ + void *newp = NULL; + + if (vmemh) { + MemHead *memh = vmemh; + memh--; + + newp = MEM_mallocN(len, memh->name); + if (newp) { + if (len < memh->len) { + /* shrink */ + memcpy(newp, vmemh, len); + } + else { + memcpy(newp, vmemh, memh->len); + + if (len > memh->len) { + /* grow */ + /* zero new bytes */ + memset(((char *)newp) + memh->len, 0, len - memh->len); + } + } } MEM_freeN(vmemh); diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 9d4704cf0f2..39424057faf 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -968,9 +968,7 @@ AviError AVI_write_frame(AviMovie *movie, int frame_num, ...) const size_t entry_size = (movie->header->Streams + 1) * sizeof(AviIndexEntry); if (movie->entries != NULL) { - temp = (AviIndexEntry *)MEM_reallocN(movie->entries, (frame_num + 1) * entry_size); - /* clear new bytes */ - memset(&temp[movie->index_entries + 1], 0, (frame_num - movie->index_entries) * entry_size); + temp = (AviIndexEntry *)MEM_recallocN(movie->entries, (frame_num + 1) * entry_size); } else { temp = (AviIndexEntry *) MEM_callocN((frame_num + 1) * entry_size, "newidxentry");