【问题标题】:Why are my vector<int>s not defaulting to 0?为什么我的 vector<int>s 没有默认为 0?
【发布时间】:2015-04-04 06:39:36
【问题描述】:

以下代码在 ideone 上运行良好,输出为

10000
10000

如预期的那样

但是在我的本地机器上,输出是这样的

9990
9998

代码所做的只是创建一个包含 10k int 的向量并计算其中 0 的数量。一次使用类,一次在 main 中。

如果我以调试模式在本地运行代码,则会导致

0
0

我在 Windows 7 上使用带有默认 GNU GCC 编译器的 codeBlocks(虽然它编译 C++,所以我猜它与只编译 C 的 Linux GCC 不同)

#include<iostream>
#include<vector>
using namespace std;
class vecttest
{
    vector<int> vect;
    public:
    vecttest()
    {
        vect.reserve(10000);
    }
    int zcount()
    {
        int count=0;
        for(int i=0;i<10000;i++)
        {
            if(vect[i]==0)
                count++;
        }
        return count;
    }
};
int main()
{
    vecttest v;
    cout<<v.zcount();

    vector<int> v2;
    v2.reserve(10000);
    int count=0;
        for(int i=0;i<10000;i++)
        {
            if(v2[i]==0)
                count++;
        }
    cout<<endl<<count;
}

ideone链接:http://ideone.com/q1XRvQ

【问题讨论】:

  • 为什么你认为它应该默认为零?你只是在保留空间
  • @EdHeal 这就是stackoverflow.com/questions/5222404/…接受的答案中提到的行为
  • 你应该使用vect.resize(10000,0);
  • @πάνταῥεῖ 谢谢,做到了..现在我看到储备没有初始化,调整大小
  • @Akash - 储备只是改变容量。调整大小会改变分配的数量

标签: c++


【解决方案1】:

reserve(..) 方法只保证分配空间。它不保证向量元素中的值。唯一会发生的事情是您的计数不会崩溃。结果值取决于实现/分配/等。

了解容器和迭代器的核心思想是它们与简单数组一样不安全:

char b1[100];
vector<char> b2(100);

void f()
{
   char c1 = b1[200];
   char c2 = b2[300];
}

在这两种情况下,编译器都会生成代码来获取数组之外的内容。这两个示例都触发了未定义的行为。也许代码会崩溃,也许不会。两种访问都同样糟糕。

这种设计的主要原因是速度。访问数组应该很快。这是 C/C++ 的核心思想。索引的值是程序员的责任。编译器不会检查。不管你喜不喜欢,就是这样。

【讨论】:

  • 计数甚至不能保证不会崩溃。从向量的实际大小之外读取是未定义的行为。 (通过对严格别名规则的一些解释,将未构造的内存区域解释为int)。
  • 严格来说你是对的。我可以打赌,没有非调试实现会崩溃。调试实现会抛出异常...
  • 调试实现肯定不会抛出异常,因为异常用于正常的错误处理。对于未定义的行为,您希望中​​止执行,以便程序员可以修复代码,但这不是您的进程可以从中恢复的东西。
猜你喜欢
  • 2010-11-28
  • 2023-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-15
  • 1970-01-01
相关资源
最近更新 更多