5

代码:

#include <valarray>
#include <iostream>    

using namespace std;

int main()
{
  valarray<int> v0(2, 4);
  valarray<int> v1;
  v1 = v0;
  cout << "v0.size: " << v0.size() << endl;
  cout << "v1.size: " << v1.size() << endl;
  cout << "v0[0]: " << v0[0] << endl;
  cout << "v1[0]: " << v1[0] << endl;
}

输出:

v0.size: 4
v1.size: 0
v0[0]: 2
Segmentation fault

对于作业:

v1 = v0;

我认为构造函数:

valarray<T>& operator=( const valarray<T>& other );

应该使用并且根据文档,我相信应该调整 v1 的大小并将 v0 的内容复制到其中,元素一个元素。那么究竟发生了什么?

$ g++ --version
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-11)
4

1 回答 1

6

因为您使用的是旧的 C++。

从 C++11 开始,目标会调整大小以匹配源。
这就是为什么这里的一些贡献者无法重现您的问题(另外,UB 有不可预测的结果)。这也是cppreference.com 文章指出首先执行调整大小的原因(尽管免责声明这仅适用于 C++11 可能已经很好)。 [这个问题现在已经修复了。]

[C++11: 23.6.2.3] valarray 赋值 [valarray.assign]

valarray<T>& operator=(const valarray<T>& v);

1数组的   每个元素*this都分配有参数数组的相应元素的值。如果 的长度v不等于 的长度,则在执行赋值之前*this调整大小*this以使两个数组的长度相同,就像通过调用 一样。resize(v.size())

2   后置条件:size() == v.size().

但是,在 C++03 中,您的代码具有未定义的行为。
这就是为什么您的旧工具链出现分段错误的原因。这也是为什么,当这个问题在 2003 年作为GCC 错误提出时,它被拒绝为无效,因为当时的实现实际上是一致的。

[C++03: 23.3.2.2] valarray 赋值 [valarray.assign]

valarray<T>& operator=(const valarray<T>& v);

1数组的   每个元素*this都分配有参数数组的相应元素的值。如果参数数组的长度不等于数组的长度,则结果行为未定义*this

于 2015-08-06T22:48:26.077 回答