I’m curious what the proper way to trim a string is to ensure that no memory leak occurs. I guess this may really be a question based on exactly how free() works. I’ve included the code for my trim() function. See below.
int main()
{
char* testStr1 = strdup("some string");
char* testStr2 = strdup(" some string");
char* testStr3 = strdup("some string ");
trim(&testStr1);
trim(&testStr2);
trim(&testStr3);
free(testStr1); // no memory leak
free(testStr2); // possible memory leak?
free(testStr3); // possible memory leak?
return 0;
}
int trim(char** pStr)
{
if(pStr == NULL || *pStr == NULL)
return FAILURE;
char* str = *pStr;
while(isspace(*str)) {
(*pStr)++;
str++;
}
if(*str == 0) {
*pStr = str;
return SUCCESS;
}
char *end = str + strlen(str) - 1;
while(end > str && isspace(*end))
end--;
*(end+1) = 0;
*pStr = str;
return SUCCESS;
}
Yes, this will cause a memory leak, but worse, it causes undefined behavior. Since
trimmodifies the pointer variables,mainpasses a pointer tofreethat was not returned bymalloc. This is undefined behavior, and it will corrupt the heap on many implementations.There are at least three correct ways to handle this.
1. Have trim allocate and return a new string, and make the caller responsible for freeing the new one, as well as the old (if needed):
2. Let the caller allocate a new string the same length (to be conservative), and pass both pointers in.
3. Trim the string in place, shifting it left: