about summary refs log tree commit diff
path: root/manual/string.texi
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2021-04-11 19:06:00 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2021-04-13 12:17:56 -0700
commitbdc674d97ba8b59e22b1f45fa1a37862764fcc75 (patch)
tree66b8438f974eb3910663d1a0f047f256de376f50 /manual/string.texi
parentcedbf6d5f3f70ca911176de87d6e453eeab4b7a1 (diff)
downloadglibc-bdc674d97ba8b59e22b1f45fa1a37862764fcc75.tar.gz
glibc-bdc674d97ba8b59e22b1f45fa1a37862764fcc75.tar.xz
glibc-bdc674d97ba8b59e22b1f45fa1a37862764fcc75.zip
Improve documentation for malloc etc. (BZ#27719)
Cover key corner cases (e.g., whether errno is set) that are well
settled in glibc, fix some examples to avoid integer overflow, and
update some other dated examples (code needed for K&R C, e.g.).
* manual/charset.texi (Non-reentrant String Conversion):
* manual/filesys.texi (Symbolic Links):
* manual/memory.texi (Allocating Cleared Space):
* manual/socket.texi (Host Names):
* manual/string.texi (Concatenating Strings):
* manual/users.texi (Setting Groups):
Use reallocarray instead of realloc, to avoid integer overflow issues.
* manual/filesys.texi (Scanning Directory Content):
* manual/memory.texi (The GNU Allocator, Hooks for Malloc):
* manual/tunables.texi:
Use code font for 'malloc' instead of roman font.
(Symbolic Links): Don't assume readlink return value fits in 'int'.
* manual/memory.texi (Memory Allocation and C, Basic Allocation)
(Malloc Examples, Alloca Example):
* manual/stdio.texi (Formatted Output Functions):
* manual/string.texi (Concatenating Strings, Collation Functions):
Omit pointer casts that are needed only in ancient K&R C.
* manual/memory.texi (Basic Allocation):
Say that malloc sets errno on failure.
Say "convert" rather than "cast", since casts are no longer needed.
* manual/memory.texi (Basic Allocation):
* manual/string.texi (Concatenating Strings):
In examples, use C99 declarations after statements for brevity.
* manual/memory.texi (Malloc Examples): Add portability notes for
malloc (0), errno setting, and PTRDIFF_MAX.
(Changing Block Size): Say that realloc (p, 0) acts like
(p ? (free (p), NULL) : malloc (0)).
Add xreallocarray example, since other examples can use it.
Add portability notes for realloc (0, 0), realloc (p, 0),
PTRDIFF_MAX, and improve notes for reallocating to the same size.
(Allocating Cleared Space): Reword now-confusing discussion
about replacement, and xref "Replacing malloc".
* manual/stdio.texi (Formatted Output Functions):
Don't assume message size fits in 'int'.
* manual/string.texi (Concatenating Strings):
Fix undefined behavior involving arithmetic on a freed pointer.
Diffstat (limited to 'manual/string.texi')
-rw-r--r--manual/string.texi41
1 files changed, 19 insertions, 22 deletions
diff --git a/manual/string.texi b/manual/string.texi
index ad11519377..7ca5ff6c94 100644
--- a/manual/string.texi
+++ b/manual/string.texi
@@ -744,19 +744,17 @@ concat (const char *str, @dots{})
 @{
   va_list ap, ap2;
   size_t total = 1;
-  const char *s;
-  char *result;
 
   va_start (ap, str);
   va_copy (ap2, ap);
 
   /* @r{Determine how much space we need.}  */
-  for (s = str; s != NULL; s = va_arg (ap, const char *))
+  for (const char *s = str; s != NULL; s = va_arg (ap, const char *))
     total += strlen (s);
 
   va_end (ap);
 
-  result = (char *) malloc (total);
+  char *result = malloc (total);
   if (result != NULL)
     @{
       result[0] = '\0';
@@ -786,45 +784,44 @@ efficiently:
 char *
 concat (const char *str, @dots{})
 @{
-  va_list ap;
   size_t allocated = 100;
-  char *result = (char *) malloc (allocated);
+  char *result = malloc (allocated);
 
   if (result != NULL)
     @{
+      va_list ap;
+      size_t resultlen = 0;
       char *newp;
-      char *wp;
-      const char *s;
 
       va_start (ap, str);
 
-      wp = result;
-      for (s = str; s != NULL; s = va_arg (ap, const char *))
+      for (const char *s = str; s != NULL; s = va_arg (ap, const char *))
         @{
           size_t len = strlen (s);
 
           /* @r{Resize the allocated memory if necessary.}  */
-          if (wp + len + 1 > result + allocated)
+          if (resultlen + len + 1 > allocated)
             @{
-              allocated = (allocated + len) * 2;
-              newp = (char *) realloc (result, allocated);
+              allocated += len;
+              newp = reallocarray (result, allocated, 2);
+              allocated *= 2;
               if (newp == NULL)
                 @{
                   free (result);
                   return NULL;
                 @}
-              wp = newp + (wp - result);
               result = newp;
             @}
 
-          wp = mempcpy (wp, s, len);
+          memcpy (result + resultlen, s, len);
+          resultlen += len;
         @}
 
       /* @r{Terminate the result string.}  */
-      *wp++ = '\0';
+      result[resultlen++] = '\0';
 
       /* @r{Resize memory to the optimal size.}  */
-      newp = realloc (result, wp - result);
+      newp = realloc (result, resultlen);
       if (newp != NULL)
         result = newp;
 
@@ -1619,8 +1616,8 @@ sort_strings_fast (char **array, int nstrings)
         @{
           /* @r{Allocate the needed space. +1 for terminating}
              @r{@code{'\0'} byte.}  */
-          transformed = (char *) xrealloc (transformed,
-                                           transformed_length + 1);
+          transformed = xrealloc (transformed,
+                                  transformed_length + 1);
 
           /* @r{The return value is not interesting because we know}
              @r{how long the transformed string is.}  */
@@ -1663,9 +1660,9 @@ sort_strings_fast (wchar_t **array, int nstrings)
         @{
           /* @r{Allocate the needed space. +1 for terminating}
              @r{@code{L'\0'} wide character.}  */
-          transformed = (wchar_t *) xrealloc (transformed,
-                                              (transformed_length + 1)
-                                              * sizeof (wchar_t));
+          transformed = xreallocarray (transformed,
+                                       transformed_length + 1,
+                                       sizeof *transformed);
 
           /* @r{The return value is not interesting because we know}
              @r{how long the transformed string is.}  */