4

I have some c++ piece of code that looks like this

StatusMessage foo() {
  ...
  if(errorCondition) {
    return StatusMessage("some custom error message");
  } else {
    return StatusMessage::OK;
  }
}

The constructor of StatusMessage takes a const char* and stores the pointer of it.

Now I would like to return a formatted string, however.

I assume the following would likely lead to a crash since the memory of not_ok is only valid during the scope of this function.

StatusMessage foo() {
  ...
  if(errorCondition) {
    char not_ok[512];
    sprintf(not_ok, "some custom error message with additional detail: %d", someInt);
    return StatusMessage(not_ok);
  } else {
    return StatusMessage::OK;
  }
}

Now, while I know the following is not clean and will overwrite the content of older StatusMessage values if the method is executed multiple times, I wonder if this is generally safe in terms of memory access (unless the message overflows the buffer):

StatusMessage foo() {
  ...
  if(errorCondition) {
    static char is_this_ok[512];
    sprintf(is_this_ok, "some custom error message with additional detail: %d", someInt);
    return StatusMessage(is_this_ok);
  } else {
    return StatusMessage::OK;
  }
}
4
  • Depends on what Status message does. I assume it's some class, that has a cosntructor that takes const char * as paramter? Does it copy that string or just store the pointer? Commented Jan 23, 2020 at 13:14
  • If the StatusMessage class stores just the pointer itself, then the static array is fine. But note that technically you're not really storing a pointer to the array, but rather only a pointer to the first element (character) of the array. Commented Jan 23, 2020 at 13:16
  • @Bob oops, it was a typo Commented Jan 23, 2020 at 13:22
  • 1
    At least make is_this_ok thread_local so you don't get races from different threads using foo() at the same time Commented Jan 23, 2020 at 13:22

1 Answer 1

6

This will work, and it is safe, but every instance of StatusMessage you create here will share the same string, so it will lead to messy code no one wants to deal with. A better thing to do is to copy the string in StatusMessage constructor. Use a std::string to manage the memory and it should work flawlessly.

If you can't change the code in StatusMessage, the solution you got there may be good enough. It depends on what you want to do. Another option is creating a wrapper class of some sort.

Sign up to request clarification or add additional context in comments.

4 Comments

The thing is I can't change the code of the StatusMessage class. It takes a const char* as argument and stores the pointer to it.
Storing every message might require considerable memory and you can't remove elements safely, because you don't know which elements are still in use somewhere.
@churill you're right. OP should really consider a wrapper class of some sort.
Can you change foo() to return a tuple of StatusMessage and allocated string (can be std::string with StatusMessage(erorr_text.c_str()))? Then you code can delete the string when the StatusMessage expires.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.