gpt4 book ai didi

c++ - 当 C++ 从函数的返回值将元素存储到 std::vector 时出现意外结果

转载 作者:IT老高 更新时间:2023-10-28 14:00:03 27 4
gpt4 key购买 nike

当函数涉及重新分配时,我发现一些编译器可能会在函数调用之前保存地址。它导致返回值存储在无效地址中。

上面的描述中有一个例子来解释行为。

#include <stdio.h>
#include <vector>
using namespace std;

vector<int> A;
int func() {
A.push_back(3);
A.push_back(4);
return 5;
}
int main() {
A.reserve(2);
A.push_back(0);
A.push_back(1);
A[1] = func();
printf("%d\n", A[1]);
return 0;
}

有一些常用的C++编译器,测试结果如下。

  • GCC(GNU Compiler Collection):运行时错误或输出 1
  • Clang:输出 5
  • VC++:输出5

这是未定义的行为吗?

最佳答案

该行为在 C++17 之前的所有 C++ 版本中未定义。原因很简单,赋值运算符的两侧可以按任意顺序求值:

  • 假设 A[1]首先评估,您会得到 int&A 的第二个元素那时。
  • 然后,func()被评估,它可以为 vector 重新分配存储空间,留下之前检索到的 int&一个悬空的引用。
  • 最后,执行分配,写入未分配的存储。由于标准分配器缓存内存,操作系统通常不会捕获此错误。

仅在 C++17 中,special rule 20已完成任务:

In every simple assignment expression E1=E2 and every compound assignment expression E1@=E2, every value computation and side-effect of E2 is sequenced before every value computation and side effect of E1

使用 C++17,A[1]必须在调用 func() 之后进行评估,然后提供定义的、可靠的行为。

关于c++ - 当 C++ 从函数的返回值将元素存储到 std::vector 时出现意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49072153/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com