2015-06-21 33 views
3

返回它的價值我有這個功能作爲一個階級的一部分,我寫:如何刪除分配的內存,並且仍然從方法

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類成員,然後用它在析構函數刪除處理,但不知何故這感覺不對,因爲它沒有其他理由類成員。

  • 我想我可以遍歷數組並將其轉換爲可以返回並轉換爲字符串的向量。但是,這種感覺並不完全正確,因爲incomingDataBuffer在某些情況下可能會很大,而且這種行爲可能會非常昂貴。

無論如何,我想這必定是一個標準方法的常見問題,那麼什麼是正確的c + +方式?

回答

1

標準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。

+0

謝謝,但這導致我第二個問題...我真的想要返回一個const char *,以便我可以cout <<我的返回值,但vector不像char [] –

+0

@SamRedway,沒有已定義的流函數您可以使用'std :: string'來代替。 'std :: string'和'vector '就這個問題非常相似 - 兩者都只是爲你管理內存的'char'動態容器。 – Barry

+0

@SamRedway或者你可以用''vector'' ['cout.write()'](http://en.cppreference.com/w/cpp/io/basic_ostream/write)。 – Barry

0

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 []在它的析構函數,以及函數返回它沒有數據的拷貝(因爲它僅僅是移動)。

0

只需使用std::vector<char>,而不是動態分配的緩衝區:一旦矢量葉在客戶端範圍

std::vector<char> incomingBuffer(this->bufferSize); 
ssize_t bytesReceived = recv(this->filedes, incomingDataBuffer.data(), this->bufferSize, flags); 
// Other stuff 
return incomingBuffer; 

這樣的內存是動態free'd。隨着C++ 11和移動語義,也不會有昂貴的向量副本。一般來說,儘量避免在現代C++中顯式的new/delete,這就是STL容器的用途。

只是爲了完整性:另一種選擇是使用std::unique_ptr<char[]>,但對於數組來說,它的語法在我看來不如std :: vectors。

相關問題