简体   繁体   中英

Eigen: Segmentation fault reading Big matrix

I use following code to map an array to matrix with Eigen:

uchar* _dataset = new uchar[number_of_labels];
Map<Matrix<uchar,Dynamic,Dynamic,RowMajor>> MNIST_dataset((uchar*)*_dataset,rows,cols);

It can be compiled. But I got segmentation fault trying to return a 280000*28 matrix as my function output. It works when the matrix size is small. Eigen doesn't limit the matrix size ,does it?

#include <iostream>
#include <string>
#include <fstream>
#include "Eigen/Dense"

using namespace Eigen;
using namespace std;
typedef unsigned char uchar;

Matrix<int,Dynamic,Dynamic,RowMajor> read_mnist_images(string full_path) {
    int number_of_images,image_size;
    auto reverseInt = [](int i) {       
        unsigned char c1, c2, c3, c4;
        c1 = i & 255, c2 = (i >> 8) & 255, c3 = (i >> 16) & 255, c4 = (i >> 24) & 255;
        return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
};
    ifstream file(full_path, ios::binary);
    int magic_number = 0, n_rows = 0, n_cols = 0;

    file.read((char *)&magic_number, sizeof(magic_number));
    magic_number = reverseInt(magic_number);
    if(magic_number != 2051) throw runtime_error("Invalid MNIST image file!");

    file.read((char *)&number_of_images, sizeof(number_of_images)), number_of_images = reverseInt(number_of_images);
    file.read((char *)&n_rows, sizeof(n_rows)), n_rows = reverseInt(n_rows);
    file.read((char *)&n_cols, sizeof(n_cols)), n_cols = reverseInt(n_cols);
    image_size = n_rows * n_cols;
    uchar** _dataset = new uchar*[number_of_images];
    for(int i = 0; i < number_of_images; i++) {
        _dataset[i] = new uchar[image_size];
        file.read((char *)_dataset[i], image_size);
    }
    n_rows = n_rows * number_of_images;
    Map<Matrix<uchar,Dynamic,Dynamic,RowMajor>> MNIST_dataset(*_dataset,n_rows,n_cols);
    return MNIST_dataset.cast<int>();
}
int main(int argc,char* argv[]){
    Matrix<int,Dynamic,Dynamic,RowMajor> dataset;
    dataset = read_mnist_images(argv[1]);
    return 0;
}

Input file can be downloaded from here

The error you made actually is to dereference the _dataset pointer by (uchar*)*_dataset , ie, you take the 0th element of your allocated array and cast that to a pointer again, which almost certainly will point to a bogus address.

Just construct your Map with the unchanged pointer:

Map<Matrix<uchar,Dynamic,Dynamic,RowMajor>> MNIST_dataset(_dataset,rows,cols);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM