c++ - 将 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;
我的理解是string
s 总是分配有一个隐藏的空元素。如果是这种情况,那么bar
真的分配了 12 个字符,第 12个是隐藏的'\0'
,这是非常安全的......如果我错了,那么cout
将导致未定义的行为,因为没有空终止符。
有人可以为我确认吗?这合法吗?
strncpy
关于为什么要使用而不是仅仅使用string(const char*, const size_t)
构造函数,有很多问题。我的意图是让我的玩具代码接近我的实际代码,其中包含一个vsnprintf
. 不幸的是,即使在这里得到很好的答案后,我发现它vsnprintf
的行为与 不一样strncpy
,并且我在这里提出了一个后续问题:为什么 vsnprintf 不写与 strncpy 相同数量的字符?
解决方案
这是安全的,只要将[0, size())
字符复制到字符串中。每[basic.string]/3
在所有情况下,
[data(), data() + size()]
是一个有效范围,data() + size()
指向具有值的对象charT()
(“空终止符”),并且size() <= capacity()
是true
.
所以string bar(length, '\0')
给你一个 asize()
为 11 的字符串,最后有一个不可变的空终止符(实际大小总共有 12 个字符)。只要您不覆盖该空终止符,或尝试将其写过去,就可以了。
推荐阅读
- cygwin - 为什么 rm 在我的 Makefile 中不起作用?使用 cygwin 和 git
- android - 如何为 Android 的内置文件选择器提供路径?
- c++ - C++ 编译器通常会“优化”malloc 并且可以自由地新建和删除吗?
- php - Laravel - 无法在 foreach 循环中保存 morphToMany 关系
- javascript - 在 Leaflet 图层上添加自定义按钮
- android - Android MediaPlayer: MediaPlayerNative: 信息/警告 (10973, 0)
- performance - Google PageSpeed:桌面和移动之间的巨大差距
- android - 后台服务是否计入 Firebase 当前的活跃用户?
- angular - Angular:无法从另一个 Angular 库中检测到打字稿工件
- javascript - 如何从 DOM 中改变元素,然后在 JavaScript 中将其返回到其原始状态?