printf_c_string (struct ui_file *stream, const char *format,
                 struct value *value)
 {
-  const gdb_byte *str;
+  gdb::byte_vector str;
 
   if (((value->type ()->code () != TYPE_CODE_PTR && value->lval () == lval_internalvar)
        || value->type ()->code () == TYPE_CODE_ARRAY)
         character.  This protects against corrupted C-style strings that lack
         the terminating null char.  It also allows Ada-style strings (not
         null terminated) to be printed without problems.  */
-      gdb_byte *tem_str = (gdb_byte *) alloca (len + 1);
+      str.resize (len + 1);
 
-      memcpy (tem_str, value->contents ().data (), len);
-      tem_str [len] = 0;
-      str = tem_str;
+      memcpy (str.data (), value->contents ().data (), len);
+      str [len] = 0;
     }
   else
     {
          return;
        }
 
-      /* This is a %s argument.  Find the length of the string.  */
-      size_t len;
-
-      for (len = 0;; len++)
+      /* This is a %s argument.  Build the string in STR which is
+        currently empty.  */
+      gdb_assert (str.size () == 0);
+      for (size_t len = 0;; len++)
        {
          gdb_byte c;
 
          QUIT;
          read_memory (tem + len, &c, 1);
+         str.push_back (c);
          if (c == 0)
            break;
        }
 
-      /* Copy the string contents into a string inside GDB.  */
-      gdb_byte *tem_str = (gdb_byte *) alloca (len + 1);
-
-      if (len != 0)
-       read_memory (tem, tem_str, len);
-      tem_str[len] = 0;
-      str = tem_str;
+      /* We will have passed through the above loop at least once, and will
+        only exit the loop when we have pushed a zero byte onto the end of
+        STR.  */
+      gdb_assert (str.size () > 0);
+      gdb_assert (str.back () == 0);
     }
 
   DIAGNOSTIC_PUSH
   DIAGNOSTIC_IGNORE_FORMAT_NONLITERAL
-    gdb_printf (stream, format, (char *) str);
+    gdb_printf (stream, format, (char *) str.data ());
   DIAGNOSTIC_POP
 }
 
   struct type *wctype = lookup_typename (current_language,
                                         "wchar_t", NULL, 0);
   int wcwidth = wctype->length ();
+  gdb::optional<gdb::byte_vector> tem_str;
 
   if (value->lval () == lval_internalvar
       && c_is_string_type_p (value->type ()))
 
       /* This is a %s argument.  Find the length of the string.  */
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-      gdb_byte *buf = (gdb_byte *) alloca (wcwidth);
+      tem_str.emplace ();
 
       for (len = 0;; len += wcwidth)
        {
          QUIT;
-         read_memory (tem + len, buf, wcwidth);
-         if (extract_unsigned_integer (buf, wcwidth, byte_order) == 0)
+         tem_str->resize (tem_str->size () + wcwidth);
+         gdb_byte *dst = tem_str->data () + len;
+         read_memory (tem + len, dst, wcwidth);
+         if (extract_unsigned_integer (dst, wcwidth, byte_order) == 0)
            break;
        }
 
-      /* Copy the string contents into a string inside GDB.  */
-      gdb_byte *tem_str = (gdb_byte *) alloca (len + wcwidth);
-
-      if (len != 0)
-       read_memory (tem, tem_str, len);
-      memset (&tem_str[len], 0, wcwidth);
-      str = tem_str;
+      str = tem_str->data ();
     }
 
   auto_obstack output;