如何解决我是否在此函数中创建了内存泄漏?
努力提高我的 C 技能。这个程序应该接受一个字符串并去掉空格。
我知道我曾两次调用 malloc
,但只调用过一次 free
。我是否因此在某处获得了一些未释放的内存,或者因为我将原始指针分配给新内存,它是否在我所做的一次 free
调用中全部消失了?
谢谢!
static void foo() {
char *string_to_change = malloc(sizeof(char) * 256);
strcpy(string_to_change,"my test");
printf("Before: %s\n",string_to_change); // "my test"
strip_whitespace(&string_to_change);
printf("After: %s\n",string_to_change); // "mytest"
free(string_to_change);
}
static void strip_whitespace(char **ptr) {
char *res = malloc(strlen(*ptr));
if (res == NULL)
exit_with_error(NULL_POINTER);
int current_pos = 0;
for (int i = 0; i < strlen(*ptr); i++) {
if (((*ptr)[i] == ' ') || ((*ptr)[i] == '\n' && ((*ptr)[i-1] == '\n' || (*ptr)[i+1] == '\0'))) {
continue;
}
res[current_pos] = (*ptr)[i];
current_pos++;
}
res[current_pos] = '\0';
*ptr = res;
}
解决方法
你这里有漏洞:
*ptr = res;
在此行之前,*ptr
指向已分配的内存块。然后将另一个分配块的起始地址分配给它,这意味着原始指针丢失。您应该在此行之前free
:
free(*ptr);
*ptr = res;
此外,此分配可能太少:
char *res = malloc(strlen(*ptr));
如果 *ptr
不包含要去除的空格,则 res
将没有足够的内存来保存终止的空字节。您需要为此加 1。
char *res = malloc(strlen(*ptr) + 1);
,
KISS principle 意味着我们应该编写尽可能简单的代码,而不是尽可能复杂。即:
- 不要将分配和算法混为一团糟。如果可能,请使用调用者分配。
- 除非明显需要,否则不要使用动态分配。
- 通常最好将字符串视为“不可变”,除非有特定要求,否则不要对它们进行就地修改。
- 避免指针对指针和对指针的奇怪算术。
- C 程序中
continue
的存在几乎表明存在不必要的复杂循环。 - 不要重新发明轮子。有
ctype.h
。
如果我们要通过调用者分配来实现这一点,代码可以归结为紧凑且易于阅读的内容,例如:
void strip_spaces (char* dst,const char* src)
{
while(*src != '\0')
{
if(!isspace(*src))
{
*dst = *src;
dst++;
}
src++;
}
*dst = '\0';
}
完整的程序:
#include <ctype.h>
#include <stdio.h>
void strip_spaces (char* dst,const char* src)
{
while(*src != '\0')
{
if(!isspace(*src)) // if not string
{
*dst = *src; // then copy
dst++;
}
src++;
}
*dst = '\0';
}
int main (void)
{
char str[] = " weird \n\r string contain ing spac\tes\n";
char stripped[128];
strip_spaces(stripped,str);
puts(stripped);
}
,
确实,您的代码中存在内存泄漏。
假设您第一次调用 malloc
在地址 0x0010 分配内存,第二次调用在地址 0x0100 分配内存。您的 free 调用将有效地释放地址 string_to_change
处的内存,即 0x0100,但没有任何内容告诉编译器释放 0x0010 处的内存.
通常,您确实必须拥有与 free
次调用一样多的 malloc
次调用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。