Adding to buffer in C ++

I am trying to efficiently convert the contents of a map to a string for sending over a socket. I still have it ...

char buffer[1024];
for (iter = my_mapy.begin(); iter != my_map.end();iter++)
{
    sprintf(buffer, "%s|%ld|%d", buffer, iter->first, iter->second);
}

      

While this works, I was wondering if it was ineffective. Google is looking for the most efficient way to convert int / long / doubles to string, resulted in sprintf so I am using it. But I'm worried that the contents of the buffer are being copied over and over, and I just want to add it to the end. Is this correct, and if so, is there a better way to do it? Performance and speed are # 1 priority.

Thank!

+3


source to share


4 answers


You're right; the solution you suggest will copy the buffer every time. To do better, you will need to use the return value of sprintf.

char buffer[1024];
char* end_of_buffer = buffer;
std::size_t remaining_space = sizeof(buffer);

for (auto iter = my_map.begin(); iter != my_map.end(); iter++)
{
    int written_bytes = snprintf(end_of_buffer, remaining_space, "|%ld|%d", iter->first, iter->second);

    if (written_bytes > 0) {
        end_of_buffer += written_bytes;
        remaining_space -= written_bytes;
    } else {
        perror("Something is wrong with the buffer");
    }
}

      



Note, by the way, that I used snprintf

which keeps track of the remaining length of the buffer. You should always use this instead of the unsafe version. Your application will evolve and with a lot of creativity you will find a way to overflow this buffer. Security, meanwhile, comes at zero additional cost.

(I mean no offense, of course.)

+5


source


You have to use std::ostringstream

s, they are efficient and more C ++ - ish:

#include <sstream>

std::ostringstream oss;
for (iter = my_mapy.begin(); iter != my_map.end();iter++)
{
    oss << iter->first << "|" << iter->second;
    //oss.str() returns the string in which everything was stored.
}

      



After that you can use operator<<

to add material at the end ostringstream

.

+5


source


You passed the buffer to sprintf, both input and output. This behavior is undefined.

+2


source


You should use stringstream instead, but if you want to be more efficient, I suppose you can use a straight char * for your buffer, you just need to make sure you grow it if you don't know it won't go over 1024 bytes.

0


source







All Articles