潜在的内存泄漏?

时间:2014-01-09 13:33:30

标签: c++ c string memory-leaks

以下代码解决了删除字符串中重复字符的问题。

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的所有空格。这是正确的吗?如果是这样,我们如何在这种情况下解决它?

6 个答案:

答案 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记录分配的字节数(通常位于malloc返回值指向的第一个字节之前的内存位置。在第三种情况下,首次加载程序时,空间仅分配一次。 / p>

不存在泄漏的可能性。