如何删除新分配的char,它也是函数返回值?

时间:2017-08-11 15:20:51

标签: c++ string stream char

归还后array1会发生什么?它会自行删除还是空间无法访问?我如何delete[]

char* ToCharArray() {

    stringstream COUT;
    COUT << *day<< "." << *month<< "." << *year<< " " << *hours<< *minutes;
    string temp = COUT.str();
    int vel = strlen(temp.size) + 1;
    char *array1= new char[vel];
    strcpy_s(array1, vel, temp.c_str());

    return array1;
}

2 个答案:

答案 0 :(得分:2)

您删除它,因为您通常会删除 C ++ 中的数组:delete[]

const char* p = ToCharArray();
// ...
delete[] p;

然而,请注意,ToCharArray()的第二部分是毫无意义的。您可能会返回std::string并避免可能的内存泄漏:

std::string ToCharArray() {
    stringstream COUT;
    COUT << *day<< "." << *month<< "." << *year<< " " << *hours<< *minutes;
    return COUT.str();
}

答案 1 :(得分:1)

在现代C ++中,尽可能避免使用原始new / new[]delete / delete[]以支持使用标准容器类和智能指针,如果你确实需要手动内存管理,那么你应该尝试尽可能地将它封装到容器类中。使用C ++ 17,你通常不需要原始指针 - 如果你有一个你不拥有的指针,你可以使用std::observer_ptr<T>来注释这个事实。特别是,智能指针类型可用于注释终身期望;例如,如果一个函数返回一个指向某个东西的指针,它希望调用者在完成它时删除它,它应该返回一个std::unique_ptr<T>。类似地,如果函数期望获取由指针传入的对象的唯一所有权并且能够在完成时释放内存,那么它应该将该参数作为std::unique_ptr<T>。给定的功能违反了这一设计原则。

但是,肯定有时候您会想要使用不遵循这些设计原则的第三方图书馆,并且您不愿意(或者可以&#39) ; t)编辑源代码。在这些情况下,我喜欢做的是在从这些API函数获取返回值后尽快创建智能指针;通过这种方式,我可以从上面为我的代码概述的现代C ++习语中获得最大的好处。在这种情况下,这看起来像:

std::unique_ptr<char[]> res { ToCharArray() };

然后,当此对象超出范围时,编译器将生成代码以释放内存。 (即使此行与包含块的末尾之间的某些内容最终抛出了未在该块中捕获的异常。)

类似地,在函数期望获取指针的所有权的情况下,我尽可能长时间地将其保留在unique_ptr<T>中,然后将p.release()作为函数的参数传递。

如果这是一个您经常使用的函数,那么围绕旧版C ++ API创建一个现代C ++包装器可能会有所帮助:

inline std::unique_ptr<char[]> wrap_ToCharArray() {
    return std::unique_ptr<char[]> { ToCharArray() };
}

这样可以带来诸如f(wrap_ToCharArray(), wrap_ToCharArray())等表达式的更好的异常安全性等好处。 (查看std::make_unique的基本原理,如果您对为什么它具有比f(std::unique_ptr<char[]> { ToCharArray() }, std::unique_ptr<char[]> { ToCharArray() })更好的异常安全性的详细信息感兴趣。)