Question

I was reading a wikipedia article on Trimming and saw this implementation of ltrim (left trim)

char *
ltrim(char *str)
{
  char *ptr;
  int  len;

  for (ptr = str; *ptr && isspace((int)*ptr); ++ptr);

  len = strlen(ptr);
  memmove(str, ptr, len + 1);

  return str;
}

Would bad things happen if I skip memmove and return ptr isntead?

char *
ltrim(char *str)
{
  char *ptr;
  int  len;

  for (ptr = str; *ptr && isspace((int)*ptr); ++ptr);

  return ptr;
}
Was it helpful?

Solution

If you return ptr -- i.e., a pointer value other than the original pointer -- and if that pointer is the only pointer to the original memory block, then no one will be able to free() it, and there will be a memory leak. You can't call free() on a pointer into the middle of an allocated block, but only on a pointer to the beginning of the block -- i.e., only on a pointer originally returned by malloc().

If for some reason you can be sure that a pointer to the original block will be preserved, or the block will never need to be freed, then the memmove() isn't needed; but those are bad assumptions for a general purpose utility routine.

OTHER TIPS

Biggest problem: This is not the way ltrim() is expected to work.

ltrim() is expected to have a side effect, to change the string in place.

For example,

char *a = " hello";
trim(a);
printf(a);

Would be expected to print "hello", but without memmove() it won't.

Edited to add:

A comment below reasonably asks, "Expected by who?"

In a language with automatic garbage collection, I expect string functions to return a new string with the desired transformation.

For those without it (which is the case here), I expect them to change the string in place, sometimes returning a pointer to the result, sometimes not.

So perhaps I should have said: This is not the way C functions are expected to work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top