malloc’ing strcat

Alexandre François Garreau galex-713@galex-713.eu
Tue Feb 25 13:04:00 GMT 2020


Le mardi 25 février 2020, 13:53:32 CET Florian Weimer a écrit :
> * Alexandre François Garreau:
> >> Sort of, except with overflow checking
> > 
> > I’m curious: how would it overflow if strlen already checks the end
> > (the \0) of each string (so that it knows how much strcat will copy)?
>
> The pointers can alias, so that the combined length of the strings is
> larger than the entire addresspace.

Alias? what does it mean? I don’t see the additional risk in respect to 
strcat…

The only thing “alias” made me think were two pointers of the array 
pointing to the same string… but that shouldn’t be that…

> >> and without the quadratic
> >> behavior.
> > 
> > Why is it quadratic? with a single loop… are you talking about calling
> > several times realloc, or strlen?
> 
> realloc and strcat look problematic.

So how’s this?
char * anstrcat (size_t n; char *strarray[])
{
  char *result, *pos = result;
  size_t total_len = 0;
  size_t *len = malloc (sizeof (size_t) * n);
  for (off_t i = 0; i < n; ++i)
    total_len += len[i] = strlen (strarray[i]);
  result = malloc (total_len + 1);
  for (off_t i = 0; i < n; ++i)
    pos = mempcpy (pos, strarray[i], len[i]);
  free(len);
  result[total_len] = '\0';
  return result;
}

To me it feels so basic to always use strcat in combination with strlen, 
that an abstraction layer above that seems necessary… don’t you think so? 
isn’t that otherwise the cause of much effort duplication?

> >> But there is another complication: The NULL sentinel is not portable
> >> because NULL can be defined as 0, which does not have the correct
> >> type
> >> for use in an argument list of character pointers.
> > 
> > And would (char*)NULL work as a replacement? otherwise how one is to
> > specify a null pointer, a null object, etc. in a portable manner?
> 
> Yes, you would have to write (char *) 0 or something like that.  Of
> course, no one does.

You said it was necessary for portability… but well I understand you don’t 
want to use NULL at all.



More information about the Libc-help mailing list