相关疑难解决方法(0)

合法覆盖std :: string的null终止符?

在C++ 11中,我们知道std::string保证是连续的和以null结尾的(或更迂腐,终止于charT(),在char空字符0 的情况下).

我需要使用这个C API,通过指针填充字符串.它写入整个字符串+ null终止符.在C++ 03中,我总是被迫使用a vector<char>,因为我无法假设它string是连续的或以null结尾的.但是在C++ 11中(假设一个合适的basic_string类,在某些标准库中仍然是不合适的),我可以.

或者我可以吗?当我这样做:

std::string str(length);
Run Code Online (Sandbox Code Playgroud)

该字符串将分配length+1字节,最后一个由null终止符填充.非常好.但是当我把它传递给C API时,它会写出length+1字符.它将覆盖null终止符.

不可否认,它将用空字符覆盖null终止.赔率是好的,这将工作(事实上,我无法想象它怎么可能不工作).

但我不关心什么"有效".我想知道,根据规范,是否可以用空字符覆盖null终止符?

c++ stdstring language-lawyer c++11

37
推荐指数
4
解决办法
3194
查看次数

非解除引用的迭代器是否超过了数组未定义行为的"一个接一个"的迭代器?

鉴于int foo[] = {0, 1, 2, 3};我想知道指向过去"一个过去"的迭代器是否无效.例如:auto bar = cend(foo) + 1;

有大量的抱怨和警告,这是Stack Overflow问题中的"未定义行为",如下所示:c ++当过去结束迭代器时,迭代器+整数的结果是什么?不幸的是,唯一的来源是挥手.

我购买它的麻烦越来越多,例如:

int* bar;
Run Code Online (Sandbox Code Playgroud)

是未初始化的,但肯定不会调用未定义的行为,并且给定了足够的尝试,我确信我可以找到一个实例,其中未初始化的值bar具有相同的值cend(foo) + 1.

这里最大的困惑之一是我不会要求解除引用cend(foo) + 1.我知道这将是未定义的行为,标准禁止它.但是这样的答案:https://stackoverflow.com/a/33675281/2642059只引用解除引用这样的迭代器是非法的,回答这个问题.

我也知道C++只保证它cend(foo)是有效的,但它可能会numeric_limits<int*>::max()在这种情况下cend(foo) + 1溢出.我对这种情况不感兴趣,除非它在标准中被调出,因为我们不能让迭代器超过"一个接一个结束".我知道这int*只是一个整数值,因此会受到溢出的影响.

我想从一个可靠的来源引用一个引用,即将迭代器移到"一个接一个"的元素之外是未定义的行为.

c++ arrays pointers iterator language-lawyer

13
推荐指数
2
解决办法
1838
查看次数

递增 std::string::end() 迭代器是否未定义?

增加 a 的end迭代器std::string以在范围中包含空终止符是否“合法” ?

例如

std::string my_text{"Arbitrary string"};
std::vector<std::uint8_t> my_collection{};
my_collection.insert(my_collection.end(), std::begin(my_text), std::next(std::end(my_text)));
Run Code Online (Sandbox Code Playgroud)

我问的原因是我只想避免my_text.c_str() + my_text.size()(或者是my_text.size()+1?)中涉及的指针算术。

我有理由相信今天的大多数实现都会按预期运行。尽管如此,对于我们中间的语言律师来说,包括 C++-legalese 的答案还是值得赞赏的。只要我在 C++ 法庭上,我就有一个严密的防御。

c++

6
推荐指数
1
解决办法
110
查看次数

标签 统计

c++ ×3

language-lawyer ×2

arrays ×1

c++11 ×1

iterator ×1

pointers ×1

stdstring ×1