0

Let me start off by saying, I know it's not ideal. What am I doing using c strings with c++? Good question, but some of the old services for the software I work with don't store dynamic memory. That being said. I'm trying to solve a frequent issues of

  • conversions of string literals to char *
  • possible buffer overflows from c methods of concatenating strings.

I ran into issues with c strings. I found this thread which has a lot of great methods for taking a stream of string literals, integers, floats, whatever, and concatenating it into a string. For nearly any one of those examples, I can do something like this:

std::string s = stringger("word1", ' ', 12345, ' ', "word2");
const char *c = s.c_str();

Below is an example of what I am hoping to do. Once again, it compiles but returns nothing.

#include <iostream>
#include <string>
#include <sstream>

template< typename ... Args >
const char* stringer(Args const& ... args )
{
    std::ostringstream stream;
    using List= int[];
    (void)List{0, ( (void)(stream << args), 0 ) ... };

    return stream.str().c_str();
}

int main()
{
    const char *s = stringer("hello", ' ', 23, ' ', 3.14, " Bye! " );

    std::cout << s << '\n';

however, when I attempt to change the return type I get nothing. It compiles, but I assume it returns null. What am I missing?

Concatenation of strings thread.

mreff555
  • 1,049
  • 1
  • 11
  • 21
  • *What am I missing?* -- A [mcve] of what you are saying does not work. Why not use `std::ostringstream`? – PaulMcKenzie Sep 03 '20 at 20:41
  • What do you mean by "changing the return type" and how do you confirm the value in `c` ? – Olivier Samson Sep 03 '20 at 20:44
  • 4
    `return stream.str().c_str();` -- Object lifetime issues on return. That stream dies, the string dies also. Why not simply return `stream.str()` and change the return type to `std::string`? – PaulMcKenzie Sep 03 '20 at 20:46
  • 2
    `stream` is dead once `stringer()` returns. You are returning an address to dead memory. – Swordfish Sep 03 '20 at 20:49
  • `but some of the old services for the software I work with don't store dynamic memory` it would be important to know how these parts use the strings and how the lifts of those strings should be handled. Without that information it is not possible to tell how you have to solve the problem. – t.niese Sep 03 '20 at 20:55
  • What kind of information specifically are you looking for? – mreff555 Sep 03 '20 at 20:56
  • 2
    *What kind of information specifically are you looking for?* – Do those C functions you want to pass the pointer alter the memory? do they expect a buffer of a specific size? do they only consume characters up to the null terminator? questions questions questions. But not for discussion here. – Swordfish Sep 03 '20 at 20:58
  • 1
    If those functions only use the passed string for the time those functions run, why don't you just return a `std::string` from `stringer` and then do `std::string str = stringer("hello", ' ', 23, ' ', 3.14, " Bye! " ); you_old_function(str.c_str());`? – t.niese Sep 03 '20 at 21:18
  • Right, that works. but I need to change it to a c-string, which is easy to do after the fact. I was just trying to do it all at once. – mreff555 Sep 03 '20 at 21:30
  • 1
    `but I need to change it to a c-string` why do you need that? Why isn‘t `you_old_function(str.c_str());` sufficient – t.niese Sep 03 '20 at 21:43
  • Your answer was useful up until the last two sentences – mreff555 Sep 03 '20 at 23:11
  • That wasn't an answer, but a question to figure out why do need to create a distinct c-string, instead of using `std::string` and only pass `c_str` to the functions of the old services. Functions like `c_str` exist so that you can pass data to functions that e.g. expect c-strings without breaking RAII. That for sure only works if those functions don't claim ownership on the passed data, as of that it is crucial to know the details about that. – t.niese Sep 04 '20 at 07:57
  • Sorry for the confusion, I was replying to swordfish, however it appears his comment was deleted. Our network layer relies on messages with fixed buffers. Byte boundaries are fixed and dynamic memory just doesn’t work. Up to packing the message, I can do whatever I want but the messages themself need to be static. – mreff555 Sep 04 '20 at 11:20

0 Answers0