简体   繁体   English

C ++。 如何正确释放内存?

[英]C++. How can I free memory correctly?

Written code to find and remove the largest word in a string without the using of library functions. 无需使用库函数即可查找和删除字符串中最大单词的书面代码。 Everything works fine. 一切正常。 But when I want to free memory, the result is negative (displays an empty line). 但是,当我要释放内存时,结果为负(显示空行)。 If you remove the call to the memory release function, everything will work correctly, but there will be a leak of memory. 如果您取消对内存释放功能的调用,则所有功能都将正常运行,但是会发生内存泄漏。 How do I fix it? 我如何解决它? Please help me. 请帮我。

#include <iostream>

using namespace std;

int length(char *text) // string length
{
    char *begin = text;
    while(*text++);

    return text - begin - 1;
}

int size(char **text) // size of two-dimensional array
{
    int i = 0;
    while(text[i]) i++;

    return i;
}

void free_memory(char **text)
{
    for(int i=0; i<size(text); i++)
        delete text[i];

    delete [] text;
}


char **split(char *text, char delim)
{
    int words = 1;
    int len = length(text);

    for(int i=0; i<len; i++)
        if(text[i] == delim) words++;

    char **result = new char*[words + 1];
    int j = 0, t = 0;

    for(int i=0; i<words; i++)
    {
        result[i] = new char[len];

        while(text[j] != delim && text[j] != '\0') result[i][t++] = text[j++];

        j++;
        t = 0;
    }

    result[words + 1] = nullptr;

    return result;
}

char *strcat(char *source, char *destination)
{
    char *begin = destination;

    while(*destination) destination++;
    *destination++ = ' ';
    while(*source) *destination++ = *source++;

    return begin;
}

char *removeWord(char *in_string)
{
    char **words = split(in_string, ' ');
    int max = length(words[0]);
    int j = 0;

    for(int i=0; i<size(words); i++)
        if(max < length(words[i]))
        {
            max = length(words[i]);
            j = i;
        }

    int index;
    char *result;

    if(!j) index = 1;
    else index = 0;

    result = words[index];

    for(int i=0; i<size(words); i++)
        if(i != j && i != index)
            result = strcat(words[i], result);

    free_memory(words); // I want free memory here

    return result;
}

int main()
{
    char text[] = "audi and volkswagen are the best car";

    cout << removeWord(text) << endl;

    return 0;
}

In fact, this is C style programming - not C++. 实际上,这是C风格的编程,而不是C ++。 I see that your aim is to implement everything from scratch, possibly for practicing. 我看到您的目标是从头开始实施所有内容,可能是为了进行练习。 But even then, your code is not designed/structured properly. 但是即使那样,您的代码也没有正确设计/构建。

Besides that, you also have several bugs in your code: 除此之外,您的代码中还存在一些错误:

  1. result[words + 1] = nullptr; must be result[words] = nullptr; 必须为result[words] = nullptr;

  2. You need result[i][t] = '\\0'; 您需要result[i][t] = '\\0'; after the while loop in split 在while循环中split

  3. delete text[i] must be delete [] text[i] delete text[i]必须为delete [] text[i]

  4. You cannot assign to your result pointer memory from words , then free it and then return it for use by the caller. 您不能从words分配result指针存储器,然后释放它,然后将其返回以供调用者使用。

  5. There is at least one further bug in the second half of removeWord . removeWord后半部分至少还有一个错误。 It would be tedious to try to understand what you are trying to do there. 试图了解您要在那里做的工作很乏味。

You might want to start with a simpler task. 您可能想从一个简单的任务开始。 You also should proceed step-by-step and check each function for correctness independently first and not implement everything and then test. 您还应该分步进行,并首先独立检查每个功能的正确性,而不先实施所有功能,然后再进行测试。 Also take a look at the tool valgrind for memory checking - if you use Linux. 还要看看用于内存检查的valgrind工具-如果使用Linux。

The way you free memory correctly is to use RAII: 正确释放内存的方法是使用RAII:

  • Only use new and new[] in constructors 仅在构造函数中使用newnew[]
  • Pair those with delete and delete[] in the corresponding destructor 将它们与相应析构函数中的deletedelete[]配对
  • Use automatic storage duration objects as much as possible 尽可能使用自动存储期限对象

If you are specifically not using std::string and std::vector etc, for reasons of learning pointers, you will end up writing some small number of classes that resemble string and vector and unique_ptr , and then you go about programming as if you were using the std versions. 如果您不是专门使用std::stringstd::vector等,则出于学习指针的原因,您最终将编写少量类似于stringvectorunique_ptr ,然后像进行编程一样进行编程使用std版本。

You have two issues. 你有两个问题。 First is that result is assigned to a memory location in words . 首先是将resultwords分配给存储位置。 Second, is that you're storing the result of strcat in words[i] which will likely not have enough room (see strcat documentation). 其次,是您将strcat的结果存储在words[i] ,这可能没有足够的空间(请参阅strcat文档)。

result = new char[len(in_string)+1]; // +1 for space for null char

// the old loop reversed the word order -- if you want to keep doing
// that, make this a descending loop
for(int i=0; i<size(words); i++)
    if(i != j && i != index)
        strcat(result, words[i]);

free_memory(words);

return result;

So that when you free words , what result points to is also free'd. 这样,当您释放words ,结果指向的内容也将被释放。 You would then need to free your result in main() . 然后,您需要在main()释放result

int main()
{
    char text[] = "audi and volkswagen are the best car";
    char * result = removeWord(text);
    cout << result << endl;

    delete[] result;

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM