将其插入没有Null终止符的字符串是否安全? [英] Is it Safe to strncpy Into a string That Doesn't Have Room for the Null Terminator?

查看:149
本文介绍了将其插入没有Null终止符的字符串是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

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 strings 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的实际代码.不幸的是,即使在这里得到了很好的答案,我仍然发现vsnprintfstrncpy的行为不同,并且我在这里提出了后续问题:

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 value charT() (a "null terminator"), and size() <= capacity() is true.

所以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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆