Com*_*riS 1 c string memory-leaks trim
我很好奇修剪字符串的正确方法是确保不会发生内存泄漏.我想这可能真的是一个基于free()工作原理的问题.我已经包含了trim()函数的代码.见下文.
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;
}
Run Code Online (Sandbox Code Playgroud)
Jer*_*fin 14
您传递给的指针free需要与从(或或)接收的指针完全相同,而不仅仅是指向返回的内存区域的指针.因此,您的第二个字符串是导致问题的字符串.你的第一个和第三个都很好,因为你传递的指针与你收到的指针(通过)匹配.malloccallocreallocmallocfreemallocstrdup
但是,在这种情况下你得到的并不是内存泄漏 - 它是未定义的行为.
是的,这会导致内存泄漏,但更糟糕的是,它会导致未定义的行为.由于trim修改了指针变量,因此main将指针传递给free未返回的指针malloc.这是未定义的行为,它会在许多实现上破坏堆.
至少有三种正确的方法可以解决这个问题.
1.修剪分配并返回一个新字符串,并让调用者负责释放新字符串以及旧字符串(如果需要):
char *trim(char *orig);
// ...
char *trimmed1 = trim(testStr1);
free(testStr1);
// ...
free(trimmed1);
Run Code Online (Sandbox Code Playgroud)
2.让调用者分配一个相同长度的新字符串(保守),然后传入两个指针.
int trim(char *orig, char *new);
// ...
char *trimmed1 = malloc(strlen(testStr1) + 1);
trim(testStr1, trimmed1);
free(testStr1);
// ...
free(trimmed1);
Run Code Online (Sandbox Code Playgroud)
3.将琴弦修剪到位,向左移动:
| | |t|r|im| | |\0|->
|t|r|i|m|\0|
int *trim(char *orig);
trim(testStr1);
// ...
free(testStr1);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
831 次 |
| 最近记录: |