X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavutil%2Fmem.c;h=15c28808c1bf0dcc9eeb00c15d0698ba5d5aaf50;hb=cf9861dea5d42d0b5a6cf0609b9624525d96c1e0;hp=b4a190ac214105a122dc81267c22a9050f5424b3;hpb=b634b36fcebfe16b837b6c4044f5d5cb99a75040;p=ffmpeg diff --git a/libavutil/mem.c b/libavutil/mem.c index b4a190ac214..15c28808c1b 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -35,6 +35,7 @@ #endif #include "avutil.h" +#include "common.h" #include "intreadwrite.h" #include "mem.h" @@ -136,29 +137,53 @@ void *av_realloc(void *ptr, size_t size) #endif } +int av_reallocp(void *ptr, size_t size) +{ + void *val; + + if (!size) { + av_freep(ptr); + return 0; + } + + memcpy(&val, ptr, sizeof(val)); + val = av_realloc(val, size); + + if (!val) { + av_freep(ptr); + return AVERROR(ENOMEM); + } + + memcpy(ptr, &val, sizeof(val)); + return 0; +} + void *av_realloc_array(void *ptr, size_t nmemb, size_t size) { - if (size <= 0 || nmemb >= INT_MAX / size) + if (!size || nmemb >= INT_MAX / size) return NULL; return av_realloc(ptr, nmemb * size); } int av_reallocp_array(void *ptr, size_t nmemb, size_t size) { - void **ptrptr = ptr; - void *ret; - if (size <= 0 || nmemb >= INT_MAX / size) + void *val; + + if (!size || nmemb >= INT_MAX / size) return AVERROR(ENOMEM); - if (nmemb <= 0) { + if (!nmemb) { av_freep(ptr); return 0; } - ret = av_realloc(*ptrptr, nmemb * size); - if (!ret) { + + memcpy(&val, ptr, sizeof(val)); + val = av_realloc(val, nmemb * size); + if (!val) { av_freep(ptr); return AVERROR(ENOMEM); } - *ptrptr = ret; + + memcpy(ptr, &val, sizeof(val)); return 0; } @@ -176,9 +201,11 @@ void av_free(void *ptr) void av_freep(void *arg) { - void **ptr = (void **)arg; - av_free(*ptr); - *ptr = NULL; + void *val; + + memcpy(&val, arg, sizeof(val)); + memcpy(arg, &(void *){ NULL }, sizeof(val)); + av_free(val); } void *av_mallocz(size_t size) @@ -194,13 +221,33 @@ char *av_strdup(const char *s) char *ptr = NULL; if (s) { int len = strlen(s) + 1; - ptr = av_malloc(len); + ptr = av_realloc(NULL, len); if (ptr) memcpy(ptr, s, len); } return ptr; } +char *av_strndup(const char *s, size_t len) +{ + char *ret = NULL, *end; + + if (!s) + return NULL; + + end = memchr(s, 0, len); + if (end) + len = end - s; + + ret = av_realloc(NULL, len + 1); + if (!ret) + return NULL; + + memcpy(ret, s, len); + ret[len] = 0; + return ret; +} + static void fill16(uint8_t *dst, int len) { uint32_t v = AV_RN16(dst - 2); @@ -324,3 +371,35 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt) *dst = *src; } } + +void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size) +{ + if (min_size < *size) + return ptr; + + min_size = FFMAX(17 * min_size / 16 + 32, min_size); + + ptr = av_realloc(ptr, min_size); + /* we could set this to the unmodified min_size but this is safer + * if the user lost the ptr and uses NULL now + */ + if (!ptr) + min_size = 0; + + *size = min_size; + + return ptr; +} + +void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size) +{ + void **p = ptr; + if (min_size < *size) + return; + min_size = FFMAX(17 * min_size / 16 + 32, min_size); + av_free(*p); + *p = av_malloc(min_size); + if (!*p) + min_size = 0; + *size = min_size; +}