如何删除新分配的字符,这也是函数返回值?

How do I delete newly allocated char that is also the function return value?

本文关键字:函数 返回值 字符 分配 何删除 删除 新分配      更新时间:2023-10-16

我归还后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;
}

您可以像通常删除数组一样删除它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();
}

在现代C++中,最好尽可能避免原始new/new[]delete/delete[],以支持使用标准容器类和智能指针,如果您确实需要手动内存管理,那么您应该尝试将其尽可能多地封装到容器类中。 对于 C++17,您通常甚至不需要原始指针 - 如果您有不拥有的指针,您可以使用std::observer_ptr<T>来注释该事实。 特别是,智能指针类型可用于注释生命周期预期;例如,如果一个函数返回一个指针,指向它希望调用者在完成它时删除的内容,它应该返回一个std::unique_ptr<T>。 同样,如果一个函数希望获得通过指针传入的对象的唯一所有权,并且能够在完成后释放内存,那么它应该将该参数作为std::unique_ptr<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())这样的表达式具有更好的异常安全性等好处。 (如果您对为什么这比f(std::unique_ptr<char[]> { ToCharArray() }, std::unique_ptr<char[]> { ToCharArray() })具有更好的异常安全性的详细信息感兴趣,请查看std::make_unique的基本原理。