简体   繁体   中英

Convert string vector to buffer

I have a string vector which contains some number of strings greater than 500. I am using openssl functions that require buffers for encryption/decryption. Given that I am using string vectors and buffers in this manner, what is the best algorithm in terms of space and time to make this conversion. Each string can be assumed to be less than 200 chars.

Currently, I am extracting each entry in paths, concatenating the strings, calling the .c_str() method and using strcpy to extract from a function.

void copy(vector<string>& paths, unsigned char** plainTextBuffer, size_t& p_len){
int size = paths.size();
int i = 0;
string temp = "";
for(i=0; i<size; i++){
  temp+= paths[i];
  temp+= "\n";
}
p_len = temp.length();
(*plainTextBuffer) = malloc(p_len + 1);
strcpy((*plainTextBuffer), temp.c_str());
return;
}

Are there any built in tools to do this better and faster? (I have excluded error checking and casting from this snippet)

Edit:

I added the +1 to the malloc. I asked for a minimum complexity manner of getting from the initial conditions to the expected output. I am using malloc because I am using a simple buffer and it is faster than new.

Edit 2:

Thanks to some of the comments I am cutting out the middleman with some of the copying and have the following

void copy(vector<string>& paths, unsigned char** plainTextBuffer, size_t& p_len){
    int size = paths.size(), total = 0, i = 0;
    for(i=0; i<size; i++){
      total+= paths[i].size() + 1;
    }
    p_len = total;
    (*plainTextBuffer) = malloc(p_len + 1);
    (*plainTextBuffer)[0] = '\0';
    for(i=0; i<size; i++){
      strcat((*plainTextBuffer), paths[i].c_str());
      strcat((*plainTextBuffer, "\n");
    }
    return;
}

Again I left out some casting. Is there a more efficient manner of getting the buffer data into the plainTextBuffer ?

The fastest way to convert a string to a C-style string is to not do any conversions. So first, let's convert our std::vector<std::string> into one std::string :

std::vector<std::string> v = ...;
std::string output;
for (auto& s : v) {
    output += s;
    output += '\n';
}

And then you can pass that in:

void some_c_api(char*, size_t );
void some_const_c_api(const char*, size_t);

some_c_api(&output[0], output.size());
some_const_c_api(output.c_str(), output.size());

Appending repeatedly into a string will result in the string repeatedly reallocating memory and shuffling its content into the new bigger space. A stringstream has a bigger creation cost, but it appends much faster than std::string, so instead of appending to a string in a loop, append to a stringstream:

stringstream temp;
for(size_t i=0; i<paths.size(); i++){
    temp << paths[i] << endl;
}
const std::string& tmp = temp.str();

Then just use tmp like you would have used your previous temp string. It is better to get a constant reference to temp.str() because it will not copy the content of the temporary created by str().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM