如何删除已分配的内存并仍然从方法返回其值
how do I delete allocated memory and still return its value from method
我将这个函数作为我正在编写的类的一部分:
const char* sockets::TCPSocket::doRecv(int flags)
{
char* incomingDataBuffer = new char [this->bufferSize];
ssize_t bytesReceived = recv(this->filedes, incomingDataBuffer, this->bufferSize, flags);
// TODO set timeout - If no data arrives, the program will just wait here until some data arrives.
if (bytesReceived == 0 || bytesReceived == -1)
{
// TODO error handling
}
// TODO avoid memory leak
// delete[] incomingDataBuffer;
// incomingDataBuffer = 0;
return incomingDataBuffer;
}
正如您所看到的,我在这里的问题是,我需要为传入字符串动态分配缓冲区大小,并且我希望将该值返回给用户。我不想让用户不得不释放内存,因为这似乎是糟糕的封装。
我的直觉是创建incomingDataBuffer c字符串的静态副本,并将其返回给我的用户。然而,尽管进行了大量的搜索,我还是找不到一种常见的方法来做这件事,这让我认为我可能只是采取了一种错误的方法。
很明显,我还有其他选择。
我可以让incomingDataBuffer成为类成员,然后在析构函数中处理它的删除,但这感觉不太好,因为它没有其他理由成为类成员。
我想我可以迭代数组并将其转换为向量,该向量可以返回并转换为字符串。但同样,这感觉不太对劲,因为在某些情况下,传入的DataBuffer可能相当大,而且这种操作可能相当昂贵。
无论如何,我想这一定是标准方法的常见问题,那么什么是正确的c++方法呢?
标准C++方法是使用std::vector
:
std::vector<char> sockets::TCPSocket::doRecv(int flags)
{
std::vector<char> incomingDataBuffer(this->bufferSize);
ssize_t bytesReceived = recv(this->filedes,
&incomingDataBuffer[0], this->bufferSize, flags);
// TODO set timeout - If no data arrives,
// the program will just wait here until some data arrives.
if (bytesReceived == 0 || bytesReceived == -1)
{
// TODO error handling
}
// on success, do this so that call site knows how much data
// there actually is
incomingDataBuffer.resize(bytesReceived);
return incomingDataBuffer;
}
由于vector
管理其内存,因此这里不存在内存泄漏的问题。通过返回它,您只是将内存管理的责任转移给调用者,但调用者不必做任何特殊的事情。当vector
超出范围时,内存自动为delete
d。
C++的方法是使用std::unique_ptr[]
。
std::unique_ptr<const char[]> sockets::TCPSocket::doRecv(int flags)
{
std::uniqure_ptr<char[]> incomingDataBuffer(new char [this->bufferSize]);
ssize_t bytesReceived = recv(this->filedes, incomingDataBuffer.get(), this->bufferSize, flags);
return incomingDataBuffer;
}
std::unique_ptr<char[]>
在它的析构函数中执行delete []
,从函数返回它不会复制数据(因为它只是被移动)。
只需使用std::vector<char>
而不是动态分配的缓冲区:
std::vector<char> incomingBuffer(this->bufferSize);
ssize_t bytesReceived = recv(this->filedes, incomingDataBuffer.data(), this->bufferSize, flags);
// Other stuff
return incomingBuffer;
这样,一旦向量离开客户端的作用域,内存就会动态释放。有了C++11和move语义,也就不会有昂贵的向量副本。一般来说,在现代C++中,尽量避免显式的新建/删除,这就是STL容器的用途。
为了完整起见:另一种选择是使用std::unique_ptr<char[]>
,但在我看来,对于数组,它的语法不如std::vectors。
- 从父类方法返回子类对象
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 让bool方法返回其他整数
- 不能将方法返回的值用于另一个方法
- 从私有成员变量的成员方法返回unique_ptr
- 我的模板类方法返回错误类型?
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 我无法使用C++指针指向类方法返回的 std::vector
- 对象引用中的字段以不同的方法返回不同的值
- 类方法返回指向具有模板的类成员的指针
- 如何将字符串从 C++/CLI 方法返回到调用它的非托管C++
- 从工厂方法返回的ComPtr的引用计数增加两次
- 如何使用 SFINAE 从 end() 方法返回 (const_) 迭代器
- Arduino trim() 和 replace() 方法返回从 'void' 到非标量类型'String'请求的转换
- 从类方法返回 "const char*" 作为 std::string&
- 如何使用 "get" 方法返回类的私有 std::unique_ptr 成员
- 可能从单个方法返回不同类型的对象
- qml 未知方法返回类型:ArchiveFile*,即使调用了 qmlRegisterUncreatableType
- 如何从方法返回静态常量 int std::array?
- 当从其他方法返回 vector 时,C++无法访问矢量元素