diff --git a/include/vlc_memstream.h b/include/vlc_memstream.h
index 0d255bb6933ec3f9e61702d4a5756dc4274aa15b..eb665bffe15c9e4ca606f8943a9f30fd5f07c33f 100644
--- a/include/vlc_memstream.h
+++ b/include/vlc_memstream.h
@@ -24,6 +24,8 @@
 # include <stdarg.h>
 # include <stdio.h>
 
+#include <vlc_vector.h>
+
 /**
  * \defgroup memstream In-memory byte streams
  * \ingroup cext
@@ -42,7 +44,10 @@ struct vlc_memstream
     union
     {
         FILE *stream;
-        int error;
+        struct {
+            int error;
+            struct VLC_VECTOR(char) vector;
+        };
     };
     char *ptr; /**< Buffer start address */
     size_t length; /**< Buffer length in bytes */
diff --git a/src/text/memstream.c b/src/text/memstream.c
index af606e063b88c1ab37830e4ffc113eed944bc904..67a8a48f7bff1aacf1a03771e738875b9d265b63 100644
--- a/src/text/memstream.c
+++ b/src/text/memstream.c
@@ -114,53 +114,56 @@ int vlc_memstream_vprintf(struct vlc_memstream *ms, const char *fmt,
 }
 
 #else
-#include <stdlib.h>
+#include <vlc_vector.h>
 
 int vlc_memstream_open(struct vlc_memstream *ms)
 {
     ms->error = 0;
-    ms->ptr = calloc(1, 1);
-    if (unlikely(ms->ptr == NULL))
+    vlc_vector_init(&ms->vector);
+    if (!vlc_vector_push(&ms->vector, '\0'))
+    {
         ms->error = EOF;
+        return EOF;
+    }
+    ms->ptr = NULL;
     ms->length = 0;
-    return ms->error;
+    return 0;
 }
 
 int vlc_memstream_flush(struct vlc_memstream *ms)
 {
-    return ms->error;
+    if (ms->error)
+        return ms->error;
+    ms->ptr = ms->vector.data;
+    ms->length = ms->vector.size - 1;
+    return 0;
 }
 
 int vlc_memstream_close(struct vlc_memstream *ms)
 {
-    if (ms->error)
+    if (vlc_memstream_flush(ms) == 0)
     {
-        free(ms->ptr);
-        ms->ptr = NULL;
+        vlc_vector_init(&ms->vector);
+        return 0;
     }
+    vlc_vector_clear(&ms->vector);
+    ms->ptr = NULL;
+    ms->length = 0;
     return ms->error;
 } 
 
 size_t vlc_memstream_write(struct vlc_memstream *ms, const void *ptr,
                            size_t len)
 {
-    size_t newlen;
-
     if (len == 0)
         return 0;
 
-    if (unlikely(ckd_add(&newlen, ms->length, len))
-     || unlikely(ckd_add(&newlen, newlen, 1)))
-        goto error;
-
-    char *base = realloc(ms->ptr, newlen);
-    if (unlikely(base == NULL))
+    size_t last = ms->vector.size;
+    if (!vlc_vector_push_hole(&ms->vector, len))
         goto error;
+    memcpy(ms->vector.data + last - 1, ptr, len);
+    ms->vector.data[ms->vector.size - 1] = '\0';
 
-    memcpy(base + ms->length, ptr, len);
-    ms->ptr = base;
-    ms->length += len;
-    base[ms->length] = '\0';
     return len;
 
 error:
@@ -183,26 +186,20 @@ int vlc_memstream_vprintf(struct vlc_memstream *ms, const char *fmt,
                           va_list args)
 {
     va_list ap;
-    char *ptr;
     int len;
-    size_t newlen;
 
     va_copy(ap, args);
     len = vsnprintf(NULL, 0, fmt, ap);
     va_end(ap);
 
-    if (len < 0
-     || unlikely(ckd_add(&newlen, ms->length, len))
-     || unlikely(ckd_add(&newlen, newlen, 1)))
+    if (len < 0)
         goto error;
 
-    ptr = realloc(ms->ptr, newlen);
-    if (ptr == NULL)
+    size_t last = ms->vector.size;
+    if (!vlc_vector_push_hole(&ms->vector, len))
         goto error;
 
-    vsnprintf(ptr + ms->length, len + 1, fmt, args);
-    ms->ptr = ptr;
-    ms->length += len;
+    len = vsnprintf(ms->vector.data + last - 1, len + 1, fmt, args);
     return len;
 
 error: