首页 > 解决方案 > 将 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;

我的理解是strings 总是分配有一个隐藏的空元素。如果是这种情况,那么bar真的分配了 12 个字符,第 12是隐藏的'\0',这是非常安全的......如果我错了,那么cout将导致未定义的行为,因为没有空终止符。

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


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

标签: c++stringc-stringsstrncpynull-terminated

解决方案


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

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

所以string bar(length, '\0')给你一个 asize()为 11 的字符串,最后有一个不可变的空终止符(实际大小总共有 12 个字符)。只要您不覆盖该空终止符,或尝试将其写过去,就可以了。


推荐阅读