C++计算std::array二维矩阵行列式时出现编译错误求助
C++行列式模板函数编译错误解决思路
问题背景
使用g++ 13.2.1编写模板函数Determinant<m>,接收std::array<std::array<int,m>,m>类型参数计算矩阵行列式,编译时出现数组大小溢出相关错误。
实现代码
Determinant函数
template <int m> int Determinant(std::array<std::array<int,m>,m> arr){ if(m == 2){ return arr[0][0]*arr[1][1] - arr[0][1]*arr[1][0]; }else if(m >2){ int ans = 0; for(int i =0;i < m;i++){ ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1); } return ans; }else{ return -1; } }
slc子矩阵生成函数
template <int m, int n> std::array<std::array<int,(n-1)>,(m-1)> slc(std::array<std::array<int,n>,m> arr, int i,int j){ std::array<std::array<int,(n-1)>,(m-1)> ans; for(int x = 0;x < m;x ++){ for (int y = 0;y < n;y++){ if(y == i || x == j){ continue; } ans[x- ( x>j ? 1:0) ][y- ( y>i ? 1:0) ] = arr[x][y]; } } return ans; }
编译错误信息
matrices.cpp: In instantiation of ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 0]’: matrices.cpp:85:42: recursively required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]’ matrices.cpp:85:42: required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]’ matrices.cpp:98:30: required from here matrices.cpp:85:51: warning: size of ‘<anonymous>’ 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=] 85 | ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1); | ~~~~~~~~^~~~~~~~~~~ matrices.cpp:85:51: warning: size of ‘<anonymous>’ 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=] In file included from matrices.cpp:2: /usr/include/c++/13/array: In instantiation of ‘struct std::__array_traits<std::array<int, 18446744073709551615>, 18446744073709551615>’: matrices.cpp:85:42: recursively required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]’ matrices.cpp:85:42: required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]’ matrices.cpp:98:30: required from here /usr/include/c++/13/array:55:13: error: size ‘18446744073709551615’ of array exceeds maximum object size ‘9223372036854775807’ 55 | using _Type = _Tp[_Nm]; | ^~~~~ /usr/include/c++/13/array: In instantiation of ‘struct std::__array_traits<int, 18446744073709551615>’: /usr/include/c++/13/array:109:55: recursively required from ‘struct std::array<int, 18446744073709551615>’ matrices.cpp:85:42: recursively required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]’ matrices.cpp:85:42: required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]’ matrices.cpp:98:30: required from here /usr/include/c++/13/array:55:13: error: size ‘18446744073709551615’ of array exceeds maximum object size ‘9223372036854775807’ matrices.cpp: In instantiation of ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 0]’: matrices.cpp:85:42: recursively required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]’ matrices.cpp:85:42: required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]’ matrices.cpp:98:30: required from here matrices.cpp:85:51: error: could not convert ‘slc<0, 0>(arr, i, 0)’ from ‘array<array<[...],4294967295>,4294967295>’ to ‘array<array<[...],18446744073709551615>,18446744073709551615>’ 85 | ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? 1:-1); | ~~~~~~~~^~~~~~~~~~~ | | | array<array<[...],4294967295>,4294967295> matrices.cpp: In instantiation of ‘std::array<std::array<int, (n - 1)>, (m - 1)> slc(std::array<std::array<int, n>, m>, int, int) [with unsigned int m = 0; unsigned int n = 0]’: matrices.cpp:85:42: recursively required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 2]’ matrices.cpp:85:42: required from ‘int Determinant(std::array<std::array<int, m>, m>) [with int m = 3]’ matrices.cpp:98:30: required from here matrices.cpp:6:43: warning: size of ‘ans’ 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=] 6 | std::array<std::array<int,(n-1)>,(m-1)> ans; | ^~~ matrices.cpp:15:10: warning: size of ‘<anonymous>’ 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=] 15 | return ans; | ^~~ matrices.cpp:15:10: warning: size of ‘<anonymous>’ 18446744039349813252 bytes exceeds maximum object size 9223372036854775807 [-Wlarger-than=]
解决思路
错误根源
递归终止条件错误:当前代码中m<=1时都返回-1,但计算3阶行列式时,递归会依次调用m=2、m=1,而m=1时代码未停止递归,反而继续调用Determinant<0>。由于std::array的大小参数是无符号整数,m-1当m=1时得到0,m=0时得到-1,转成无符号后变成超大值(如18446744073709551615),导致数组大小超出系统限制,触发编译错误。
修复步骤
修正递归终止条件:
当m == 1时,直接返回矩阵唯一元素arr[0][0],避免递归到m=0;同时修正代数余子式的符号(原代码符号写反):template <int m> int Determinant(std::array<std::array<int,m>,m> arr){ if(m == 1){ return arr[0][0]; }else if(m == 2){ return arr[0][0]*arr[1][1] - arr[0][1]*arr[1][0]; }else if(m >2){ int ans = 0; for(int i =0;i < m;i++){ ans += arr[0][i]*Determinant<m-1>(slc<m,m>( arr,i,0 ))*(i%2 ? -1 : 1); } return ans; }else{ return -1; } }添加模板参数合法性检查:
使用static_assert在编译期限制m必须大于等于1,提前拦截非法的矩阵大小:template <int m> int Determinant(std::array<std::array<int,m>,m> arr){ static_assert(m >= 1, "Matrix size must be a positive integer"); // ... 剩余代码 ... }验证slc函数逻辑:
当m=2、n=2时,slc函数返回std::array<std::array<int,1>,1>,符合1阶矩阵的要求,此时递归到Determinant<1>即可正确返回结果,不会触发m=0的实例化。
内容的提问来源于stack exchange,提问作者Advaith GS
相关产品推荐
相关产品推荐

