Каковы различия valarray в gcc и msvc (или Linux и Windows)

Я испытываю различное поведение valarray в Windows и Linux. Кто-нибудь знает об этом или знает, где посмотреть? Очевидно, что одна версия, работающая на обеих системах, является верной 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 (myValues) уже инициализировано. Это не кажется необходимым на MSVC / Windows. Я мог позвонить myValues.resize(1) на Linux, и это работает так же.

Теперь, кто-нибудь знает точно о различиях или ресурс в Интернете? Есть ли лучшие практики, как работать с valarray?

Версии программного обеспечения:

  • Windows 7, MS Visual Studio 2010 SP1, компилятор Visual C ++ 16.00.40219.01 для 80×86
  • 64-разрядная версия Lubuntu 14.04 на виртуальной машине, 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. Обратите внимание на объявление и предварительную инициализацию myValues ​​внутри цикла for, там, где выполняется нарезка.

#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,

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 как пустой valarray с размером 0. Условие использования 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,

1

Другие решения


По вопросам рекламы [email protected]