1

我在 Windows 和 Linux 中遇到了不同的 valarray 行为。有谁知道这个或知道在哪里看?很明显,在这两个系统上运行的一个版本是正确的 C++,但为什么另一个在 Windows 上工作?valarray的实现还有更多的区别吗?

在 MSVC/Windows 上工作但在 gcc/Linux 上不工作的代码示例:

    valarray<signed short> myValues;
    for(size_t s = 0; s < 10; s++)
    {
        slice dataSlice(1, 1, 1);
        // on Linux, this slice operation gives me a segmentation fault
        myValues= RawData[dataSlice];
    }

我跟踪它以修复 gcc/Linux 版本的代码:

    for(size_t s = 0; s < 10; s++)
    {
        slice dataSlice(1, 1, 1);
        valarray<signed short> myValues = RawData[dataSlice];
    }

gcc/Linux 版本期望 l-value (myValues) 已经初始化。这在 MSVC/Windows 上似乎没有必要。我可以调用myValues.resize(1)Linux,它也可以工作。

现在,有谁知道确切的差异或互联网上的资源?是否有如何使用 valarray 的最佳实践?

软件版本:

  • Windows 7、MS Visual Studio 2010 SP1、Visual C++ 编译器 16.00.40219.01 用于 80x86
  • 虚拟机上的 Lubuntu 14.04 64 位,GNU Make 3.81,GCC 4.8.2

感谢大家。


更新:详细的代码示例。是否编译。第一个示例在 Linux 中给出了分段错误,但在 Windows 中运行良好。

// This example compiles both on Windows with MSVC and on Linux with GCC.
// It gives a segmentation fault in Linux.
// It gives the expected output on Windows.

#include "stdafx.h"

#include <iostream>
#include <valarray>

int main(int argc, char **argv) {

  //init base data

  std::valarray<signed short> myData(10);
  for (int i = 0; i < 10; i++)
  {
    myData[i] = i;
  }

  std::valarray<signed short> myValues;

  for (int i = 0; i < 10; i++)
  {
    myValues = myData[std::slice(0, i, 1)];
    std::cout << "myValues: ";

    for (size_t k = 0; k < myValues.size(); k++)
    {  
        std::cout << myValues[k] << ",";
    }

    std::cout << std::endl;
  }
}

以下示例在 Linux 和 Windows 上运行良好。注意 for 循环中 myValues 的声明和初始化,就在切片完成的地方。

#include "stdafx.h"

#include <iostream>
#include <valarray>

int main(int argc, char **argv) {

  //init base data

  std::valarray<signed short> myData(10);
  for (int i = 0; i < 10; i++)
  {
    myData[i] = i;
  }

  for (int i = 0; i < 10; i++)
  {
    std::valarray<signed short> myValues = myData[std::slice(0, i, 1)];
    std::cout << "myValues: ";

    for (size_t k = 0; k < myValues.size(); k++)
    {  
        std::cout << myValues[k] << ",";
    }

    std::cout << std::endl;
  }
}

预期输出:

myValues:
myValues: 0,
myValues: 0,1,
myValues: 0,1,2,
myValues: 0,1,2,3,
myValues: 0,1,2,3,4,
myValues: 0,1,2,3,4,5,
myValues: 0,1,2,3,4,5,6,
myValues: 0,1,2,3,4,5,6,7,
myValues: 0,1,2,3,4,5,6,7,8,
4

1 回答 1

1

valarray.assign/8

valarray<T>& operator=(const slice_array<T>&);
valarray<T>& operator=(const gslice_array<T>&);
valarray<T>& operator=(const mask_array<T>&);
valarray<T>& operator=(const indirect_array<T>&);

要求:参数引用的数组的长度等于size()

您创建myValues为大小为 0 的空。不满足valarray使用的先决条件。valarray<T>& operator=(const slice_array<T>&);

代替

myValues = myData[std::slice(0, i, 1)];

auto s = std::slice(0, i, 1);
myValues.resize(s.size());
myValues = myData[s];

或者

myValues = std::valarray<signed short>(myData[std::slice(0, i, 1)]);

它会起作用。

我还不明白为什么slice_array<T> operator[](slice slicearr)选择而不是valarray<T> operator[](slice slicearr) const.

于 2014-11-12T14:05:56.373 回答