Skip to content

ostream::operator<< output shows wrong # of values for 2-d array if strides unusual #57

Description

@r-owen

The following sample code produces very odd output to cout using operator<< in the second case (doTranspose == 1):

#include <iostream>
#include <vector>
#include "ndarray.h"

int main() {
    // include extra values to avoid reading off the end
    std::vector<double> xvec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};

    int const len = 3;
    auto shape1d = ndarray::makeVector(len);
    auto strides1d = ndarray::makeVector(1);
    // create x = {1, 2, 3} and y = {4, 5, 6}
    ndarray::Array<double, 1, 1> x = ndarray::external(xvec.data(), shape1d, strides1d);
    ndarray::Array<double, 1, 1> y = ndarray::external(xvec.data() + len, shape1d, strides1d);
    std::cout << "x = " << x << std::endl;
    std::cout << "y = " << y << std::endl;

    for (int doTranspose = 0; doTranspose < 2; ++doTranspose) {
        auto xyshape = ndarray::makeVector(2, static_cast<int>(x.getSize<0>()));
        std::cout << "\nxyshape = " << xyshape << std::endl;
        auto xystrides = ndarray::makeVector(&y[0] - &x[0], static_cast<std::ptrdiff_t>(1));
        if (doTranspose) {
            std::cout << "transpose xystrides: [[1, 4, 7], [2, 5, 8]]" << std::endl;
            xystrides[1] = xystrides[0];
            xystrides[0] = 1;
        } else {
            std::cout << "normal xystrides: [[1, 2, 3], [4, 5, 6]])" << std::endl;
        }
        std::cout << "xystrides = " << xystrides << std::endl;
        ndarray::Array<double, 2, 1> xy = ndarray::external(x.getData(), xyshape, xystrides);
        std::cout << "xy.getSize<0>() = " << xy.getSize<0>() << "; xy.getSize<1>() = " << xy.getSize<1>() << std::endl;

        for (auto row = 0; row < xy.getSize<0>(); ++row) {
            for (int col = 0; col < xy.getSize<1>(); ++col) {
                std::cout << "xy[" << row << "][" << col << "] = " << xy[row][col] << std::endl;
            }
        }

        std::cout << "xy = " << xy << std::endl;
    }
}

On my system (clang 8.1.0 on macOS) all output is as expected except the final cout<<, which looks screwy and has far too many values:

x = [       1, 2, 3]
y = [       4, 5, 6]

xyshape = (2,3,)
normal xystrides: [[1, 2, 3], [4, 5, 6]])
xystrides = (3,1,)
xy.getSize<0>() = 2; xy.getSize<1>() = 3
xy[0][0] = 1
xy[0][1] = 2
xy[0][2] = 3
xy[1][0] = 4
xy[1][1] = 5
xy[1][2] = 6
xy = [[       1, 2, 3], 
[       4, 5, 6]]

xyshape = (2,3,)
transpose xystrides: [[1, 4, 7], [2, 5, 8]]
xystrides = (1,3,)
xy.getSize<0>() = 2; xy.getSize<1>() = 3
xy[0][0] = 1
xy[0][1] = 4
xy[0][2] = 7
xy[1][0] = 2
xy[1][1] = 5
xy[1][2] = 8
xy = [[       1, 2, 3, 4, 5, 6, 7, 8, 9], 
[       2, 3, 4, 5, 6, 7, 8, 9, 10]]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions