SparseMatrix reallocation throws std::bad_alloc when StorageIndex > Eigen::Index

Submitted by Robin Deits

Assigned to Nobody

Link to original bugzilla bug (#1706)
Version: 3.3 (current stable)

Description

It appears that the internal resize methods for SparseMatrix spuriously throw std::bad_alloc when using a SparseMatrix whose StorageIndex is of a wider integer type than Eigen::Index.

For example, consider the following snippet, in which we construct a SparseMatrix using 64-bit StorageIndex in a context where Eigen::Index is a 32-bit integer:

#define EIGEN_DEFAULT_DENSE_INDEX_TYPE int32_t  
#include <Eigen/Core>  
#include <Eigen/Sparse>  
  
int main() {  
	Eigen::SparseMatrix<double, Eigen::ColMajor, int64_t> mat(5, 5);  
	for (int i = 0; i < 5; i++) {  
		for (int j = 0; j < 5; j++) {  
			mat.coeffRef(i, j) = 1;  
		}  
	}  
	return 0;  
}  

Compiling this with:

g++ main.cpp -o main -Ieigen-3.3.7 -std=c++11  

(assuming the Eigen sources live in ./eigen-3.3.7) and running it with ./main will abort with:

terminate called after throwing an instance of 'std::bad_alloc'  
  what():  std::bad_alloc  
Aborted (core dumped)  

The issue appears to stem from the following line in SparseCore/CompressedStorage.h:

Index realloc_size = (std::min<Index>)(NumTraits<StorageIndex>::highest(),  size + Index(reserveSizeFactor*double(size)));  

when StorageIndex is wider than Index, this results in realloc_size being set to -1, which triggers the internal::throw_std_bad_alloc() on the next line.

Blocking

#1608

Edited by Charles Schlosser