将其插入没有Null终止符的字符串是否安全?

Jon*_*Mee 1 c++ string c-strings null-terminated strncpy

考虑以下代码:

const char foo[] = "lorem ipsum"; // foo is an array of 12 characters
const auto length = strlen(foo); // length is 11
string bar(length, '\0'); // bar was constructed with string(11, '\0')

strncpy(data(bar), foo, length);
cout << data(bar) << endl;
Run Code Online (Sandbox Code Playgroud)

我的理解是strings始终分配有一个隐藏的null元素。如果是这种情况,那么bar实际上会分配12个字符,其中第12 字符是隐藏的'\0',这是绝对安全的...如果我错了,那cout将导致未定义行为,因为没有空终止符。

有人可以帮我确认吗?这合法吗?


关于为什么要使用strncpy而不是仅使用string(const char*, const size_t)构造函数存在很多问题。我的目的是使玩具代码接近包含的实际代码vsnprintf。不幸的是,即使在这里获得了出色的答案之后,我仍然发现它的vsnprintf行为与并不相同strncpy,并且我在这里提出了一个后续问题:为什么vsnprintf不会写与strncpy相同数量的字符?

Nat*_*ica 5

只要将[0, size())字符复制到字符串中,这是安全的。每[basic.string] / 3

在所有情况下,[data(), data() + size()]都是有效范围,data() + size()指向具有值的对象charT()(“空终止符”),并且size() <= capacity()true

因此string bar(length, '\0'),您将得到一个字符串,其a size()为11,最后一个不可变的空终止符(实际大小总共为12个字符)。只要您不覆盖该空终止符,或者不尝试重写它,就可以了。