以下代码解决了删除字符串中重复字符的问题。
void removeDuplicatesEff(char *str)
{
if (!str)
return;
int len = strlen(str);
if (len < 2)
return;
const int sz = (1<<CHAR_BIT);
bool hit[sz] = {false};
int tail = 0;
for (int i=0; i<len; ++i)
{
if (!hit[str[i]])
{
str[tail] = str[i];
++tail;
hit[str[i]] = true;
}
}
str[tail] = 0;
}
在最后一步中设置str[tail]=0
后,如果char *str
确实包含重复字符,则其大小会更小,即tail
。但我想知道这里是否有内存泄漏?在我看来,以后,我们无法释放分配给原始char *str
的所有空格。这是正确的吗?如果是这样,我们如何在这种情况下解决它?
答案 0 :(得分:3)
在我看来,以后,我们无法释放分配给原始char * str的所有空格。这是对的吗?
没有。零终止字符串的长度与分配的内存缓冲区的大小完全分离,系统将单独处理它。只要每个分配后面都进行了对称解除分配(例如每个free
操作都有malloc
),那么您就是安全的。
但我想知道这里是否有内存泄漏?
可以说,是的,这是仍然泄漏,因为它(暂时)使用的内存超过了所需的内存。但是,这通常不是问题,因为内存最终会被释放。除非在非常特殊的情况下,因此不会将其视为泄漏。
那就是说,代码是非常规的,并且肯定比必要的长(它还假设CHAR_BIT == 8
但这是另一回事)。例如,您可以更轻松地初始化标志数组,从而节省循环:
bool hit[256] = {false};
为什么你的循环在一个基础上越过字符串,为什么第一个字符是单独处理的?
答案 1 :(得分:2)
不,没有泄漏。您只需输入0
而不是其长度来修改数组的内容。
此外,您不应通过hit
- 循环分配来初始化for
数组。标准初始化
bool hit[256] = { 0 };
就足够了,可以通过最有效的初始化形式由编译器替换。
答案 2 :(得分:2)
您的情况下没有内存泄漏。从头部分配内存并在使用后不释放内存泄漏。在您的情况下,您没有从堆分配任何内存。您正在使用存储在堆栈中的局部变量,并在控制从该函数返回时释放。
答案 3 :(得分:1)
您正在做的只是更改终结符字符的位置。它实际上并没有改变分配的内存的大小。它实际上是一种非常常见的操作,并且没有内存泄漏的风险。
答案 4 :(得分:1)
不,你不会有内存泄漏。在delete []
上执行free()
或str
将解除分配所有已分配的内存,因为该信息存储在其他位置,并且不依赖于str
中存储的数据类型。
答案 5 :(得分:1)
但我想知道这里是否有内存泄漏?在我看来,以后,我们无法释放分配给原始char * str
的所有空格
这里可能没问题。 str
的存储空间已按以下方式之一分配:
在第一种情况下,当堆栈框架展开时,所有空间都会消失。在第二种情况下,malloc记录分配的字节数(通常位于malloc返回值指向的第一个字节之前的内存位置。在第三种情况下,首次加载程序时,空间仅分配一次。 / p>
不存在泄漏的可能性。