Is it well-defined behavior to return a vector of const char*, filled inside a function
Asked Answered
L

1

7

I am currently learning vulkan. In one of the tutorials I saw a function which roughly does the following:

#define SOMESTRING "Hello World!"

std::vector<const char*> buildVector() {
    std::vector<const char*> vec;
    vec.push_back(SOMESTRING);
    return vec;
}

When I saw this, I was wondering: is this defined behavior? Isn't the content of the string "Hello World!" located on the stack and thus is invalid once the function returns? If this is undefined behavior, what would be the correct way to do this? Unfortunately, using std::string is not an option because of the vulkan API.

Lammas answered 15/1, 2017 at 16:52 Comment(2)
Same as const char* stuff() { return SOMESTRING; }. The vector doesn't do anything magical here.Chism
String literals are lvalues with static storage duration.Acculturate
S
6

Yes, because SOMESTRING's scope (viz. value represented by that macro) belongs to static storage, i.e. string literals have full lifetime of the program execution. And that is your case here.


Here are various scenarios:

  • #define SOMESTRING "Hello World!"
    --> OK. String literals are stored in static storage & hence their lifetime is from program's beginning till end

  • const char* SOMESTRING = "Hello World!"
    --> OK. Same as above.

  • char SOMESTRING[] = "Hello World!";
    --> OK, iff it's declared in a static or extern scopes.
    --> BAD, if this array is declared within a function as a non-static.

  • char* SOMESTRING = new char[X]; strncpy(SOMESTRING, "Hello World!", N);
    --> OK, because the string's storage is now in free store (i.e. heap) & will remain so until it's deleted. The catch is that, the strings stored in vector have to be freed up later to prevent memory leak.

BTW, std::vector doesn't influence the define/undefine-ness of the behaviour; In this case here it depends on the C-style string literals only as illustrated above.

Splayfoot answered 15/1, 2017 at 16:58 Comment(1)
SOMESTRING doesn't have a "scope". It's a macro, whose expansion is a literal, not a name. Only names have scopes. And "full lifetime" isn't a type of lifetime in C++.Acculturate

© 2022 - 2024 — McMap. All rights reserved.