diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 926c966..7e3b7bf 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2017-08-29  Tom Tromey  <tom@tromey.com>
+
+	* valprint.c (val_print_string): Update.
+	* gdbcore.h (memory_error_message): Return std::string.
+	* corefile.c (memory_error_message): Return std::string.
+	(memory_error): Update.
+	* breakpoint.c (insert_bp_location): Update.
+
 2017-08-28  Simon Marchi  <simon.marchi@ericsson.com>
 
 	PR gdb/21827
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index ae09da4..e1fb6b5 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -2889,16 +2889,14 @@ insert_bp_location (struct bp_location *bl,
 		{
 		  if (bp_err_message == NULL)
 		    {
-		      char *message
+		      std::string message
 			= memory_error_message (TARGET_XFER_E_IO,
 						bl->gdbarch, bl->address);
-		      struct cleanup *old_chain = make_cleanup (xfree, message);
 
 		      fprintf_unfiltered (tmp_error_stream,
 					  "Cannot insert breakpoint %d.\n"
 					  "%s\n",
-					  bl->owner->number, message);
-		      do_cleanups (old_chain);
+					  bl->owner->number, message.c_str ());
 		    }
 		  else
 		    {
diff --git a/gdb/corefile.c b/gdb/corefile.c
index d9773cf..5631347 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -186,7 +186,7 @@ Use the \"file\" or \"exec-file\" command."));
 }
 
 
-char *
+std::string
 memory_error_message (enum target_xfer_status err,
 		      struct gdbarch *gdbarch, CORE_ADDR memaddr)
 {
@@ -195,11 +195,11 @@ memory_error_message (enum target_xfer_status err,
     case TARGET_XFER_E_IO:
       /* Actually, address between memaddr and memaddr + len was out of
 	 bounds.  */
-      return xstrprintf (_("Cannot access memory at address %s"),
-			 paddress (gdbarch, memaddr));
+      return string_printf (_("Cannot access memory at address %s"),
+			    paddress (gdbarch, memaddr));
     case TARGET_XFER_UNAVAILABLE:
-      return xstrprintf (_("Memory at address %s unavailable."),
-			 paddress (gdbarch, memaddr));
+      return string_printf (_("Memory at address %s unavailable."),
+			    paddress (gdbarch, memaddr));
     default:
       internal_error (__FILE__, __LINE__,
 		      "unhandled target_xfer_status: %s (%s)",
@@ -213,12 +213,10 @@ memory_error_message (enum target_xfer_status err,
 void
 memory_error (enum target_xfer_status err, CORE_ADDR memaddr)
 {
-  char *str;
   enum errors exception = GDB_NO_ERROR;
 
   /* Build error string.  */
-  str = memory_error_message (err, target_gdbarch (), memaddr);
-  make_cleanup (xfree, str);
+  std::string str = memory_error_message (err, target_gdbarch (), memaddr);
 
   /* Choose the right error to throw.  */
   switch (err)
@@ -232,7 +230,7 @@ memory_error (enum target_xfer_status err, CORE_ADDR memaddr)
     }
 
   /* Throw it.  */
-  throw_error (exception, ("%s"), str);
+  throw_error (exception, ("%s"), str.c_str ());
 }
 
 /* Helper function.  */
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
index 87f3dcd..a25a231 100644
--- a/gdb/gdbcore.h
+++ b/gdb/gdbcore.h
@@ -37,11 +37,11 @@ extern int have_core_file_p (void);
 
 extern void memory_error (enum target_xfer_status status, CORE_ADDR memaddr);
 
-/* The string 'memory_error' would use as exception message.  Space
-   for the result is malloc'd, caller must free.  */
+/* The string 'memory_error' would use as exception message.  */
 
-extern char *memory_error_message (enum target_xfer_status err,
-				   struct gdbarch *gdbarch, CORE_ADDR memaddr);
+extern std::string memory_error_message (enum target_xfer_status err,
+					 struct gdbarch *gdbarch,
+					 CORE_ADDR memaddr);
 
 /* Like target_read_memory, but report an error if can't read.  */
 
diff --git a/gdb/valprint.c b/gdb/valprint.c
index eef99b1..5b02e2f 100644
--- a/gdb/valprint.c
+++ b/gdb/valprint.c
@@ -2988,13 +2988,10 @@ val_print_string (struct type *elttype, const char *encoding,
 
   if (err != 0)
     {
-      char *str;
-
-      str = memory_error_message (TARGET_XFER_E_IO, gdbarch, addr);
-      make_cleanup (xfree, str);
+      std::string str = memory_error_message (TARGET_XFER_E_IO, gdbarch, addr);
 
       fprintf_filtered (stream, "<error: ");
-      fputs_filtered (str, stream);
+      fputs_filtered (str.c_str (), stream);
       fprintf_filtered (stream, ">");
     }
 
