将其插入没有Null终止符的字符串是否安全? [英] Is it Safe to strncpy Into a string That Doesn't Have Room for the Null Terminator?
问题描述
考虑以下代码:
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;
我的理解是string
始终分配有隐藏的null元素.如果是这种情况,那么bar
实际上会分配12个字符,而第12个 th 是隐藏的'\0'
,这是绝对安全的...如果我错了,那么
My understanding is that string
s are always allocated with a hidden null element. If this is the case then bar
really allocates 12 characters, with the 12th being a hidden '\0'
and this is perfectly safe... If I'm wrong on that then the cout
will result in undefined behavior because there isn't a null terminator.
有人可以帮我确认吗?这合法吗?
Can someone confirm for me? Is this legal?
关于为什么使用strncpy
而不是仅使用string(const char*, const size_t)
构造函数存在很多问题.我的目的是使玩具代码接近包含vsnprintf
的实际代码.不幸的是,即使在这里得到了很好的答案,我仍然发现vsnprintf
与strncpy
的行为不同,并且我在这里提出了后续问题:
There have been a lot of questions about why to use strncpy
instead of just using the string(const char*, const size_t)
constructor. My intent has been to make my toy code close to my actual code which contains a vsnprintf
. Unfortunately even after getting excellent answers here I've found that vsnprintf
doesn't behave the same as strncpy
, and I've asked a follow up question here: Why is vsnprintf Not Writing the Same Number of Characters as strncpy Would?
推荐答案
这是安全的,只要将[0, size())
字符复制到字符串中即可.每个 [basic.string]/3
This is safe, as long as you copy [0, size())
characters into the string . Per [basic.string]/3
在所有情况下,
[data(), data() + size()]
是有效范围,data() + size()
指向具有值charT()
(空终止符")的对象,而size() <= capacity()
是true
.
In all cases,
[data(), data() + size()]
is a valid range,data() + size()
points at an object with valuecharT()
(a "null terminator"), andsize() <= capacity()
istrue
.
所以string bar(length, '\0')
为您提供一个size()
为11的字符串,结尾处有一个不可变的空终止符(实际大小总共为12个字符).只要您不覆盖该空终止符,或者不尝试重写它,就可以了.
So string bar(length, '\0')
gives you a string with a size()
of 11, with an immutable null terminator at the end (for a total of 12 characters in actual size). As long as you do not overwrite that null terminator, or try to write past it, you're okay.
这篇关于将其插入没有Null终止符的字符串是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!