带结构元素的std :: vector的大小

时间:2010-10-31 04:13:11

标签: c++ size stdvector

我无法使用struct元素获得正确大小的矢量。元素类是这样定义的(我没有省略任何细节,即使我认为唯一相关的事实是它是一个包含int和两个双精度的类):

class Interval
{
public:
    Interval(int _i = 0, scalar _l = 0, scalar _r = 0) :
        index(_i),
        l(_l),
        r(_r)
    { }

    inline double left(void)    const { return l; }
    inline double right(void)   const { return r; }

    inline bool operator < (const Interval & i2) const { return left() < i2.left(); }

public:
    int index;
    double l;
    double r;

};

然后在函数中我有这段代码:

std::vector<Interval> arr(10);
int s1 = arr.size();
int s2 = arr.end() - arr.begin();

我获得的s1的值是15,而s2是正确的值10.发生了什么?是不是size()应该准确返回元素的数量?它不应该与arr.end() - arr.begin()?

相同

感谢任何回复和评论。

4 个答案:

答案 0 :(得分:1)

首先在格式化代码时停止使用HTML标记。请改为使用[代码]按钮。

其次,你所描述的是一个无视任何解释的谜。您应该在10s1中获得相同的值 - s2 - 。除非你以某种方式设法在其他代码中破坏了向量的完整性(即你运行的代码不是你向我们展示的代码)。

答案 1 :(得分:1)

Codepad

中按预期工作

答案 2 :(得分:0)

编辑:既然您已经提供了更多信息,或许我们可以对这种令人困惑的行为有所了解。

您违反了One Definition Rule。这样做的结果并没有真正定义,但我们可以根据你观察到的结果做一些有根据的猜测。

模板函数始终以内联方式声明,因为这是模板参数替换所必需的。当编译器遇到其中一个函数时,它可以选择将其作为内联代码发送或创建函数体并调用它。如果它创建了一个函数体,则链接器负责消除不同转换单元中的重复定义。链接器没有做太多检查以查看明显的重复是否在功能上等效,它只是取决于函数的修饰名称,这取决于参数的类型;如果类型都具有相同的名称,则假定它们是相同的。由于一个定义规则,它可以做出这个假设。

这就是如何让源代码中未包含的类定义影响代码的结果 - 链接器将代码的错误副本替换为良好的代码。如果编译器生成内联代码,您将获得预期的结果,如果链接器涉及到您有50/50的机会得到错误的东西。即使你的代码很幸运,其他一些代码现在也被破坏了。

<小时/> 原始答案: 矢量可能大于请求的大小,但size不会反映该值;您可以使用capacity进行测试。多余的存储将是内存使用的一部分,但元素不会被初始化,任何超出size结果的访问尝试都将导致未定义的行为。

答案 3 :(得分:0)

更新:在探索项目中的代码库之后,我在其他人编写的另一个头文件中找到了另一个同名“Interval”的类(我很难选择像我的类名这样简单的单词)。该类包含两个双精度数(我的机器上有16个字节,而我的类有24个字节),这似乎解释了为什么size()调用返回的元素数比实际数量多50%。

但我不明白std :: vector如何被两个定义混淆(我的代码中没有包含该标题,但是我的标题可能包含在该标题后包含在项目的其他部分中),以及end() - begin()如何使用一个定义,而size()使用另一个定义。

顺便说一句,为了避免在多程序员项目中发生此类冲突,最佳做法是使用命名空间,对吧?感谢。