当矩阵大小超过特征矩阵类型的特定限制时,c ++分配错误
c++ bad allocation when matrix size exceeds a certain limit with Eigen matrix type
在 C++ 动态库中,我使用 Eigen Library 解决了一个最小二乘问题。这个Dll是在一个python软件里面调用的,问题配置已经解决了。在一个小问题中,代码可以正常工作并且 returns 是正确的解决方案。如果点数增加,则库抛出 std::bad_alloc
.
更准确地说,最简化错误的代码是
try {
matrixA = new Eigen::MatrixXd(sizeX,NvalidBtuple); // initialize A
for (int i=0;i<sizeX;++i) {
int secondIndex = 0;
for (int k=0;k<btermSize;++k) {
if (bterm[k] == 1) { // select btuple that are validated by density exclusion
// product of terms
(*matrixA)(i,secondIndex) = 1.0;
secondIndex += 1;
}
}
}
} catch (std::bad_alloc& e) {
errorString = "Error 3: bad allocation in computation of coefficients!";
std::cout<<errorString<<" "<<e.what()<<std::endl;
return;
} catch (...) {
errorString = "Error 4: construction of matrix A failed! Unknown error.";
std::cout<<errorString<<std::endl;
return;
}
其中matrixA
在头文件中定义为Eigen::MatrixXd *matrixA;
。
如果 sizeX
和 NvalidBtuple
小于大约 20'000x3'000,则矩阵定义有效。如果尺寸更大,它会崩溃。
我测试的电脑有足够的可用内存,大约15G可用内存。
这是一个 heap/stack 问题吗?
如何让库接受更大的矩阵?
欢迎任何评论。谢谢。
编辑:
如下面的回答所述,我不清楚 NvalidBtuple
定义:
NvalidBtuple = 0;
for (int i=0;i<btermSize;++i) {NvalidBtuple += bterm[i];}
其中 bterm
是一个布尔向量。因此,由于在循环中我们进行检查 if (bterm[k] == 1)
,secondIndex
总是小于 NvalidBtuple
.
从你问题的细节来看,矩阵需要 480Mb 的 RAM。 32 位应用程序只能访问 2Gb 的 RAM(参见 How much memory can a 32 bit process access on a 64 bit operating system?);分配失败,因为在应用程序的地址 space 中没有可用的 continuous 480Mb 块。
解决该问题的最佳方法是将应用程序重新编译为 64 位。您将无法在 32 位系统中 运行 它,但这应该不是问题,因为您无论如何都无法 运行 在这样的系统上使用您的算法,因为有限记忆。
在 C++ 动态库中,我使用 Eigen Library 解决了一个最小二乘问题。这个Dll是在一个python软件里面调用的,问题配置已经解决了。在一个小问题中,代码可以正常工作并且 returns 是正确的解决方案。如果点数增加,则库抛出 std::bad_alloc
.
更准确地说,最简化错误的代码是
try {
matrixA = new Eigen::MatrixXd(sizeX,NvalidBtuple); // initialize A
for (int i=0;i<sizeX;++i) {
int secondIndex = 0;
for (int k=0;k<btermSize;++k) {
if (bterm[k] == 1) { // select btuple that are validated by density exclusion
// product of terms
(*matrixA)(i,secondIndex) = 1.0;
secondIndex += 1;
}
}
}
} catch (std::bad_alloc& e) {
errorString = "Error 3: bad allocation in computation of coefficients!";
std::cout<<errorString<<" "<<e.what()<<std::endl;
return;
} catch (...) {
errorString = "Error 4: construction of matrix A failed! Unknown error.";
std::cout<<errorString<<std::endl;
return;
}
其中matrixA
在头文件中定义为Eigen::MatrixXd *matrixA;
。
如果 sizeX
和 NvalidBtuple
小于大约 20'000x3'000,则矩阵定义有效。如果尺寸更大,它会崩溃。
我测试的电脑有足够的可用内存,大约15G可用内存。
这是一个 heap/stack 问题吗? 如何让库接受更大的矩阵?
欢迎任何评论。谢谢。
编辑:
如下面的回答所述,我不清楚 NvalidBtuple
定义:
NvalidBtuple = 0;
for (int i=0;i<btermSize;++i) {NvalidBtuple += bterm[i];}
其中 bterm
是一个布尔向量。因此,由于在循环中我们进行检查 if (bterm[k] == 1)
,secondIndex
总是小于 NvalidBtuple
.
从你问题的细节来看,矩阵需要 480Mb 的 RAM。 32 位应用程序只能访问 2Gb 的 RAM(参见 How much memory can a 32 bit process access on a 64 bit operating system?);分配失败,因为在应用程序的地址 space 中没有可用的 continuous 480Mb 块。
解决该问题的最佳方法是将应用程序重新编译为 64 位。您将无法在 32 位系统中 运行 它,但这应该不是问题,因为您无论如何都无法 运行 在这样的系统上使用您的算法,因为有限记忆。