va_arg访问违规



我正在尝试创建一个函数,该函数在参数中获取可变数量的矩阵并将这些矩阵乘以第一个矩阵。 我可以使用va_arg读取第一个,但是下一次调用va_arg将导致访问冲突。

这是我声明我的方法的方式:

template<class MType>
static CMatrice<MType> COperationsComplexesMatricesPassages::OCPChangementDeBase
(CMatrice<MType> & MATVecteur, unsigned int uiNbMatricesPassages,
CMatricePassage<MType> MAPMatrices...)

这是我如何称呼它:

COperationsComplexesMatricesPassages::OCPChangementDeBase(mat1, 2, matP1, matP2)

异常出现在我的方法主体中for(...)的第一个va_arg上。 这是我的方法的代码:

unsigned int uiIndice;
unsigned int uiBaseArriveePrecedente;
va_list args;
va_start(args, MAPMatrices);
CMatrice<MType> MATResult(MATVecteur);
CMatricePassage<MType> MAPMatricePass = va_arg(args, CMatricePassage<MType>);
MATResult = MATResult * MAPMatricePass;
uiBaseArriveePrecedente = MAPMatricePass.MAPGetBaseArrivee();
for (uiIndice = 1; uiIndice < uiNbMatricesPassages; uiIndice++) {
CMatricePassage<MType> MAPMatricePass2 = va_arg(args, CMatricePassage<MType>);
if (uiBaseArriveePrecedente != MAPMatricePass2.MAPGetBaseDepart()) {
CException EXCError(EXC_ChangementImpossible);
throw EXCError;
}
uiBaseArriveePrecedente = MAPMatricePass2.MAPGetBaseArrivee();
MATResult = MATResult * MAPMatricePass2;
}
return MATResult;

无论如何,我不明白您到底想从OCPChangementDeBase()方法中获得什么......也许我错了...但在我看来,关于可变参数函数,有几个重要的观点是你不知道的。

(1)旧的C变奏语法

void foo (int a, int b...)

并不意味着b是整数的可变参数列表。

该声明等效于 (最后一个逗号是可选的)

void foo (int a, int b, ...)

因此,对于这两个声明,您都有一个b整数(单个整数b整数)和一个未命名的可变参数列表。

所以给你的方法

template<class MType>
static CMatrice<MType>
COperationsComplexesMatricesPassages::OCPChangementDeBase
(CMatrice<MType> & MATVecteur, unsigned int uiNbMatricesPassages,
CMatricePassage<MType> MAPMatrices...)

并称它

COperationsComplexesMatricesPassages::OCPChangementDeBase(mat1, 2, matP1, matP2)

你有那个

  • MATVecteur变得mat1
  • uiNbMatricesPassages变得2
  • MAPMatrices变得matP1
  • 未命名的可变参数列表...变得matP2

因此,如果您期望在未命名的varidic列表中有两个参数,那么您只有一个参数,我对"下一次调用va_arg将导致访问冲突"并不感到惊讶。

(2)旧的C可变参数语法(va_listva_arg,基于va_start)在C++中仍然可用,但据我所知,仅适用于POD(普通旧数据)类型。

所以,据我所知,你的代码是UB(未定义的巴哈维),因为matP2(我想)不是POD。

幸运的是,C++(从 C++11 开始)引入了可变参数模板,这些模板也与非 POD 类型兼容。

所以,我想,你算写你的方法如下或类似的东西

template <typename MType, typename ... MTs>
static auto COperationsComplexesMatricesPassages::OCPChangementDeBase
(CMatrice<MType> & MATVecteur, MTs ... MAPMatrices)
{
auto MatResult { MatVectour };
( MatResult *= MapMatrices, ... ); // template folding; only from C++17
return MatResult;
}

您还可以添加一些约束(查找 SFINAE)以强制规定MTs...类型完全(或者,也许更好,可转换为)CMatricePassage<MType>(或者另一种类型,如果需要)。

相关内容

  • 没有找到相关文章

最新更新