如何修剪字符数组时释放内存?

时间:2015-01-20 17:52:53

标签: c++

我用C ++编写代码。我当前的问题是我必须从字符数组的开头修剪空格。我不允许使用任何字符串函数。我的想法是在开始时计算空白的数量,根据我在字符数组中需要的内存量来分配内存,如果我没有这些空格,那么这样做,然后复制新的字符串并释放原始字符串。

我的问题是,如果没有Visual Studio为我打破一个断点,我似乎无法解除分配该字符串。我可以使用下面的代码(不要解除roginal strig)d =但这不会导致内存泄漏吗?

提前感谢您的帮助。

#include <iostream>
using namespace std;

class SmartString{  
    private:
        char* str;
    public:
        SmartString ( )
        {
            str = NULL;
        }
        SmartString (char *str){
            int length = 0;
            int copy_index = 0;
            while(str[length] != '\0')
            {
                length++;
            }
            length++;
            char * copy;
            copy = (char*)malloc(sizeof(char) * length);
            copy = new char[length];
            while(copy_index < length)
            {
                copy[copy_index] = str[copy_index];
                cout << str[copy_index];
                copy_index++;
            }
            this -> str = copy;
        }
        ~ SmartString()
        {
            if(str != NULL)
            {
                delete str;
                free(str);
            }
        }
        void ShowString()
        {
            cout << "[" << str << "]";
        }
        int Size()
        {
            if(str == NULL)
                return 0;
            else
            {
                int i = 0;
                while(str[i] != '\0')
                {
                    i++;
                }
                i++;
                return i;
            }
        }
        **void Trim()
        {
            int counter = 0;
            while (str[counter] == ' ' && counter < Size())
            {
                counter++;
            }       
            int new_length = Size() - (counter + 1);
            char * temp;
            temp = (char*) malloc(sizeof(char) * new_length);
            temp = new char[new_length];
            int counter_2 = 0;
            while(counter_2 < Size())
            {
                temp[counter_2] = str[counter_2 + counter];
                counter_2++;
            }
            str = temp;
        }** 
};

int main()
{
    char *str;
    str = "   Hello";
    SmartString * s = new SmartString(str);
    str = "Change";
    (*s).Trim();
    (*s).ShowString();

    system("Pause");
}

2 个答案:

答案 0 :(得分:0)

我认为有三种合理的方法。

一种是就地修改现有字符串。找到第一个非空格字符的位置,然后从那里复制到字符串的末尾到从字符串的第一个元素开始的位置。这不能应用于字符串文字(或者您将获得未定义的行为)。

第二种方法是分配一个新缓冲区并将要保留的数据复制到该缓冲区中。在这种情况下,您可能想要尝试修改原始文件(尤其是,您不想尝试释放其数据)。

第三个是(基本上)重新实现一个类似于std::string的类,它总是以特定的方式分配一个缓冲区,所以它&#34;知道&#34;如何安全地操纵缓冲区。在这种情况下,你可以/将有一个构造函数从字符串文字创建一个对象,所以当你的函数被调用时,它只会(甚至尝试)操纵这些对象,并且永远不会意外地尝试操纵/修改某些东西就像一个字符串文字。

答案 1 :(得分:0)

你没有在main函数中使用'delete'来释放你的''指针变量,所以你的'SmartString'类的析构函数方法永远不会被调用。在你的第二个constrcutor方法中,我已经将'copy'变量分配了两次不需要的地方。你的'Trim'方法也有一些错误。

在析构函数方法中,您应该删除free(str);语句,因为delete str;语句将释放'str'。所以没有必要解除分配两次。

malloc - 分配请求的内存并返回指向它的指针 new X; - 执行相同的操作,但如果X是分配后的类或结构,也会调用构造函数方法 new X[] - 使用请求的内存分配动态数组并返回指向它的指针。

free - 释放先前分配的内存 delete - 执行相同的操作,但如果X在解除分配后是一个类或结构,也会调用析构函数方法。
delete[] - 释放先前分配的动态数组的内存。

newdelete是C ++语言的标准内存分配和释放实现,其中mallocfree是C语言的标准内存分配和释放函数。 / p>

在这里,我重写了你的'修剪'方法:

void Trim()
    {
        int counter = 0;
        while (str[counter] == ' ' && counter < Size())
        {
            counter++;
        } 
        int new_length = Size() - (counter + 1);
        char * temp;
        // There is no need to allocate twice
        //temp = (char*) malloc(sizeof(char) * new_length);
        temp = new char[new_length+1];
        int counter_2 = 0;
        while(counter_2 < //Size() ( Here is your big mistake. You should not use 'Size()' here )
                          new_length
                          )
        {
            temp[counter_2] = str[counter_2 + counter];
            counter_2++;
        }
        temp[counter_2] = 0;

        str = temp;
    }

要解除分配,你必须像这样使用'删除':

int main() 
{
    char *str;
    str = "   Hello";
    SmartString * s = new SmartString(str);
    str = "Change";
    (*s).Trim();
    (*s).ShowString();

    // use delete to deallocate a pointer
    delete s;

    system("pause");
}