【问题标题】:Why does the same code run differently in Visual Studio and Dev-C++? [duplicate]为什么相同的代码在 Visual Studio 和 Dev-C++ 中的运行方式不同? [复制]
【发布时间】:2015-07-03 01:34:25
【问题描述】:
#include <iostream>
#include <vector> 
using namespace std;
int main() 
{
    vector<int> v(10,0);
    vector<int>::iterator ff = v.begin();
    v.assign(3, 11);
    cout << *ff << endl;
    cin.get();
    return 0;
    return 0;
}

猜测:

编译器有问题? 有什么我不知道的?

详情:

当我看到在 c++ api 中指定向量的函数时。 偶然我想知道向量中分配的存储空间以及是否可以使用迭代器作为指针。 所以我写这个。 但它错了。我想也许在通话时分配它重新分配内存。 但我谷歌它。它说

“当且仅当新向量大小超过当前向量容量时,这会导致分配的存储空间自动重新分配。”

显然功能很大,所以它不应该重新分配。我疯了,我尝试了 devc++,它很好。为什么?

【问题讨论】:

  • v.assign() 使您的迭代器无效,从而导致未定义的行为。
  • 什么?无效...T_T 好吧...谢谢..
  • 迭代器可以被定义为指针(根据标准),如果你的向量导致重新分配,它不知道有多少迭代器(这对于开销+非常复杂的重新分配来说真的是个坏主意时间方面),所以它基本上不在乎。举个例子:迭代器的开始是 0x00AA,当你插入它时,它变成了 0x0A00,但是你的迭代器仍然指向 0x00AA,它现在被定义为“免费抓取”(已删除),所以 UB 发生了跨度>
  • 在 C++ 标准库中,指定了迭代器失效的各种场景,并且对于不同的容器是不同的。如果您有某种需要,您可以选择具有不同(更强?)失效保证的不同容器。

标签: c++ visual-studio vector iterator dev-c++


【解决方案1】:

这是由于在调用 v.assign() 后使用迭代器时未定义的行为,因为 assign 会使迭代器无效,因此在调用后使用迭代器是个坏主意。

有趣的是,VS 在调用 assign 之后确实重用了相同的底层内存(它仍然有相同的地址,容量为 10,但新的大小为 3),但它有一个名为 Debug Iterators 的功能。当此功能开启时,就像 Debug 构建的默认设置一样,它会存储有效迭代器的列表,因此知道您的迭代器已失效并很好地告诉您。在更快的 Release 构建中,它不会运行这些检查,因此它具有未定义的行为,但恰好打印出正确的值。

具有不太复杂的迭代器调试机制的编译器不会这样做,并且您会得到未定义的行为(这会以最可怕的方式表现出来 - 完全按照您的预期行事)

如果您碰巧存储了指向第一个元素的指针,那么即使是调试迭代器也无法帮助您,您可能会得到您期望打印的值,但它仍然是未定义的行为!

【讨论】:

  • 非常感谢!!!我尝试发布,它真的运行了。所以它可以使用,但是当使用 assign vs flag 之前的迭代器无效时,我使用 invalidates 迭代器 vs 警告错误。跨度>
猜你喜欢
  • 1970-01-01
  • 2015-03-07
  • 2022-01-23
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多