Is std::array<char, size> null terminated?

Viewed 272

Is the following snippet of code safe? It invoked std::string's fourth constructor that takes in a pointer to a null terminated string. The thing is, I'm not sure if word below is null terminated. Is it?

std::array<char, 4> word{'a', 'b', 'c', 'd'};

int main()
{
    std::string p = word.data();
    return 0;
}
4 Answers

Is std::array<char, size> null terminated?

It can contain a null terminated string. It doesn't necessarily contain a null terminated string.

std::array<char, 4> word{'a', 'b', 'c', 'd'};

This array does not contain a null terminated string. You can tell because none of the elements are the null terminator character.

std::string p = word.data();

The behaviour of this program is undefined.

Is the following snippet of code safe?

No.


how to make word null terminated.

Here is one example:

std::array<char, 5> word{'a', 'b', 'c', 'd'};

Or if you want to be more explicit:

std::array<char, 5> word{'a', 'b', 'c', 'd', '\0'};

This array is non null-terminated. One easy way to make it null-terminated would be to initialize it from string literal like that:

std::array<char, 5> a{"abcd"};

Is the following snippet of code safe?

No. It is invoking Undefined Behavior.

It invoked std::string's fourth constructor that takes in a pointer to a null terminated string. The thing is, I'm not sure if word below is null terminated. Is it?

No, it is not.

A simple fix, assuming you don't want to null-terminate the array, would be to use a different std::string constructor that takes in the desired length as a parameter, eg:

std::array<char, 4> word{'a', 'b', 'c', 'd'};

int main()
{
    std::string p(word.data(), word.size());
    // more generally:
    // std::string p(word.data(), desired_length);
    return 0;
}

Alternatively, you can use a different std::string constructor that takes in iterators instead, eg:

std::array<char, 4> word{'a', 'b', 'c', 'd'};

int main()
{
    std::string p(word.begin(), word.end());
    // more generally:
    // std::string p(word.begin(), word.begin() + desired_length);
    return 0;
}

Either way, you don't need a null terminator.

If your goal is to initialize the std::string with a null terminated string in the std::array but not over running the bounds, you can use std::find like this:

std::string p{std::begin(word), std::find(std::begin(word), std::end(word), '\0')};

It will initialize either up to the first null terminator or the end of the array if there is no null terminator.

Related