2

I want to do the following:

std::unique_ptr<char[]> buffer = new char[ /* ... */ ] { "/tmp/file-XXXXXX" };

Obviously, it doesn't work because I haven't specified the size of a new array. What is an appropriate way to achieve my goal without counting symbols in a string literal?

Usage of std::array is also welcome.

Update #1: even if I put the size of array, it won't work either.

Update #2: it's vital to have a non-const access to the array as a simple char* pointer.

1
  • 1
    A dynamic arrays of chars, so you mean a string - which incidentally offers the right constructor too. Well sizeof("/tmp/lala") will work for the size if it's a constant (that includes the \0 too though so be careful). Commented Dec 30, 2014 at 15:02

3 Answers 3

4

Here's a solution based on std::array:

std::array<char, sizeof("/tmp/file-XXXXXX")> arr{ "/tmp/file-XXXXXX" };

You can reduce the boilerplate using a macro:

#define DECLARE_LITERAL_ARRAY(name, str) std::array<char, sizeof(str)> name{ str }
DECLARE_LITERAL_ARRAY(arr, "/tmp/file-XXXXXX");

The sizeof is evaluated at compile-time, so there is no runtime scanning of the literal string to find its length. The resulting array is null-terminated, which you probably want anyway.

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

Comments

2

Since you requested a dynamic array and not wanting to count the length, that rules out std::array<char,N>. What you're asking for is really just std::string - it's dynamic (if need be), and initializes just fine from a char* without counting the length. Internally, it stores the string in a flat array, so you can use it as such, via the c_str() call.

13 Comments

I don't want string since the array will go as non-const char* to mkstemp()
Exactly right, but a small example of initializing a string object with a literal string, and then calling c_str in order to retrieve the char array would make this answer even better.
Ah, you didn't specify the whole problem! Since mkstemp() modifies its argument, you're right that we need non-const memory. Two options: const_cast<char*>(str.c_str()) ... which is awful, but it's your string and mkstemp() doesn't change the length, so it might be ok. Or you will need to count chars and use the std::array. Or you can do: char* buf = new char[strlen(template)]; copy(template.begin(),template.end(),buf.begin());
@JHUmphrey Casting const away is not an option. It's not just awful but simply illegal (exhibits undefined behavior) as far as I can see.
@Voo: It may be awful but it's only illegal if str.c_str() != &str[0], otherwise the original storage is guaranteed to be mutable and hence const can be legally cast away.
|
1

I don't get why you're not using std::string; you can do str.empty() ? NULL : &str[0] to get a non-const pointer, so the constness of str.c_str() is not going to pose a problem.

However, note that this is not null-terminated.

Comments

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.