0

I am writing a socket server in C++ and need to wrapper the read function, from an std::string buffer. As you can see in the below code for reading a single byte (ClientConnection.readByte), it uses a char to store the value, delete it, then return the char. However I also want to implement a readEverything (ClientConnection.readEverything) function, which should return the entire buffer. Right now, I just copy the buffer, but this doesn't seem memory efficient. This would be easy if I could return before readBuffer.erase(), but that can't work. Is there an efficient workaround, or do I just have to use my original method?

class ClientConnection{
private:
    int connfd;
    std::string writeBuffer;
    std::string readBuffer;
    struct sockaddr *address;
public:
    ClientConnection(int fd){
        connfd = fd;
    }
    bool available(){
        char toReturn;
        recv(connfd, &toReturn, 1, MSG_PEEK);
        return toReturn!=-1;
    }
    char readByte(){
        char thingy = readBuffer[0];
        readBuffer.erase(0, 1);
        return thingy;
    }
    std::string readEverything(){
        std::string readBufferCopy = readBuffer;
        readBuffer.erase();
        return readBufferCopy;
    }
    void writeByte(char byte){
        writeBuffer += byte;
    }
    void polleverything(){
        write(connfd, writeBuffer.c_str(), writeBuffer.length());
        char readBuffer[READOUTBUFFERSIZE];
        while (recv(connfd, &toReturn, READOUTBUFFERSIZE, 0) == READOUTBUFFERSIZE){
            std::cout << "HELLO";
        };
    }
};

The ClientConnection class is supposed to be passed file descriptors and otherwise used by a server class, which for the sake of easy-reading I omitted from this snippet.

Thanks in advance!

nerdguy
  • 174
  • 1
  • 16
  • Do you have some guarantee that the buffer won't be overwritten by the time the user uses its data? Are you confident that every part of the program would get that right? Copying seems much safer and much less complex. – chris Mar 17 '21 at 15:00
  • 2
    You might be able to do `std::string readBufferCopy = std::move(readBuffer);` and then hope that your compiler cooperates and does NVRO. – Sam Varshavchik Mar 17 '21 at 15:03
  • @SamVarshavchik, That part's okay since no NRVO means it's still moved out if using a standard from within the last decade (same requirement as moving the data out of the buffer in the first place). – chris Mar 17 '21 at 15:06
  • But without NVRO a copy is still made. Granted, it's now one copy instead of two, so that's definitely progress, but without guaranteed copy elision you must still have to do a copy. – Sam Varshavchik Mar 17 '21 at 15:20
  • @SamVarshavchik, Where? It'd be moving data out of the buffer to the local variable and then moving data out of the local variable into the return value. – chris Mar 17 '21 at 15:37
  • The return itself is NVRO, which is not guaranteed, and thus can involve a copy. – Sam Varshavchik Mar 17 '21 at 15:39
  • @SamVarshavchik, The alternative to NRVO here [is a move, not a copy](http://eel.is/c++draft/class.copy.elision#3). This is the reason for [the common advice](https://stackoverflow.com/questions/17473753/c11-return-value-optimization-or-move) not to `return std::move(local);`—either it would've been NRVOd but now can't be, or it would have been moved anyway and the call is redundant. All that is to say that if the poster is using C++11 or later, your comment is pretty ideal. – chris Mar 17 '21 at 15:50

0 Answers0