在函数内取消分配动态内存

Pic*_*u64 5 c++ c++11

第一次在这里拥有帐户,但是我很喜欢这个网站。

我试图创建一个接收const char数组并返回所述数组指示的部分的函数。函数与数组一起接收两个值,这些值指示要提取的部分中第一个字符的索引和最后一个字符的索引。

我要尝试的棘手部分是,我正在创建一个临时数组变量以将该部分保存在函数中,并且鉴于该部分的大小不能保证为常数,我正在使用动态内存进行分配必要的空间,这就是我遇到的问题。

每当函数返回任何信息时,函数都会终止,并且程序没有机会释放已分配的内存。如果删除该变量,则无法返回信息。

我尝试创建一个单独的指针变量,以在信息形成后指向该信息,但是一旦释放了内存,该信息似乎就无法恢复。

解决问题的程序:

char* seperateString(const char* a, int b, int c) {

                // This is simply to assure that I don't allocated a negative size
        if (b < c) {
                cout << "***Error with \"seperateString\" function***" << endl << endl;
                return '\0';
        }

        char* seperated = new char[c - b + 2];

        int i = 0;
        int j = b;

        for (; i <= c - b; i++)
                seperated[i] = a[j++];

        seperated[i] = '\0';

        char* send = seperated;
        delete[] seperated;

        return send;
}

int main() {
        cout << "Program Iniciated." << endl << endl;

        const int a = 6, b = 11;


        const char* toBeSeperated = "Hello there, I have missed you.";
        char *ari = seperateString(toBeSeperated, 6, 11);

        cout << "Sentence is: " << toBeSeperated << endl << endl
            << "Extracted portion is: " << ari << endl << endl;

        cin.get();
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

程序按主要功能的预期工作。

int main() {
        cout << "Program Iniciated." << endl << endl;

            // variable a and b hold the beginning and last index values of the portion 
            // that is wanted to extract. 
        const int a = 6, b = 11;


            // This is an example sentence  |------| this is the portion being extracted.
        const char* toBeSeperated = "Hello there, I have missed you.";

            // variable holding extracted portion.
            // created with the size necessary to hold the portion plus a \0.
        char* seperated = new char[b  -a  +2];
                                                                //Given that a and b are index values 1 has to be added for size
                                                                //Additionally an extra space is require for \0

            //i is held outside the for loop to allow to access it after it completes the cycle
          //so it's able to assing \0 after the last character.
        int i = 0;

          //j holds the value of the first index
        int j = a;

        for (; i <= b - a; i++)
                seperated[i] = toBeSeperated[j++];

        seperated[i] = '\0';

        cout << "Sentence is: " << toBeSeperated << endl << endl
                << "Extracted portion is: " << seperated << endl << endl;

        delete[] seperated;
        cin.get();
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

最后,这是关于防止内存泄漏。

Skr*_*ino 7

正如您所指出的,我们必须具有实际存储函数结果的内存,因此我们无法在返回之前释放动态分配的数组。剩下两个选择:

  1. 在调用之前分配内存,并提供指向被调用函数的指针和该内存的大小(不够优雅)
  2. 确保我们以安全的方式将指针传递回分配的内存

但是,在两种情况下,我们都必须确保手动释放内存。智能指针非常适合此用例,特别是std :: unique_ptr

这是一个正常运行的程序:

#include <iostream>
#include <memory>

std::unique_ptr<char[]> seperateString(const char* a, int b, int c) {
    using namespace std;
    // This is simply to assure that I don't allocated a negative size
    if (c < b) {
        cout << "***Error with \"seperateString\" function***" << endl << endl;
        return '\0';
    }

    auto seperated = std::unique_ptr<char[]>(new char[c - b + 2]);

    int i = 0;
    int j = b;

    for (; i <= c - b; i++)
        seperated[i] = a[j++];

    seperated[i] = '\0';

    return seperated;
}

int main() {
    using namespace std;
    cout << "Program Iniciated." << endl << endl;

    const int a = 6, b = 11;


    const char* toBeSeperated = "Hello there, I have missed you.";
    auto ari = seperateString(toBeSeperated, 0, 5);

    cout << "Sentence is: " << toBeSeperated << endl << endl
        << "Extracted portion is: " << ari.get() << endl << endl;

    cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

唯一指针获取动态分配资源的所有权,并在离开作用域时销毁资源本身时释放(即释放)资源。

在函数中seperateString,我们unique_ptr通过操作符构造一个指向动态分配的字符数组的指针new[]。从这一点开始,我们不需要管理动态分配的内存,因为它已绑定到智能指针的生存期seperated。无论何时seperated销毁,其析构函数都会delete[]在构造时分配给我们的数组指针上调用operator 。

但是,等待,seperated在函数返回时被销毁了,难道我们不回到第一个平方,因为在我们可以在调用代码中使用它之前释放了内存?不,因为我们要返回unique_ptr<char[]>按值,所以编译器将资源所有权从函数本地seperated唯一指针移动到调用站点本地ari唯一指针,并通过move-constructor构造它。现在,在函数调用中分配的内存的命运与的生存期相关ari,并且当超出范围时,内存将被释放而不会泄漏。