下面的函数获取指向API_AddParType
结构的指针数组的指针,并列出每个数组元素的一些字段。当使用(*ppParams)[ii]
访问每个元素时,一切都像预期的那样:
void ParamsListWrapper::ListParams2(API_AddParType** ppParams)
{
unsigned long ii, nParams;
nParams = BMGetHandleSize( (GSHandle)ppParams ) / sizeof(API_AddParType);
// list params
for ( ii = 0; ii < nParams; ii++ ) {
WriteReport( "Param name = \"%s\", double = %f", (*ppParams)[ii].name, (*ppParams)[ii].value.real );
}
}
好吧,让我们使用像API_AddParType& param
这样的参考变量:
void ParamsListWrapper::ListParams1(API_AddParType** ppParams)
{
unsigned long ii, nParams;
nParams = BMGetHandleSize( (GSHandle)ppParams ) / sizeof(API_AddParType);
// list params
for ( ii = 0; ii < nParams; ii++ ) {
API_AddParType& param = (*ppParams)[ii];
WriteReport( "Param name = \"%s\", double = %f", param.name, param.value.real );
}
}
现在尝试使用指向API_AddParType
的相同代码:
void ParamsListWrapper::ListParams3(API_AddParType** ppParams)
{
unsigned long ii, nParams;
nParams = BMGetHandleSize( (GSHandle)ppParams ) / sizeof(API_AddParType);
// list params
for ( ii = 0; ii < nParams; ii++ ) {
API_AddParType* pParam = ppParams[ii];
if (pParam != NULL) {
WriteReport( "Param name = \"%s\", double = %f", pParam->name, pParam->value.real );
} else {
WriteReport( "Param is NULL" );
}
}
}
有分段错误。怎么会这样?为什么它在通过指针访问数据时失败而引用工作没有任何问题?
答案 0 :(得分:1)
尝试将API_AddParType* pParam = ppParams[ii];
更改为API_AddParType* pParam = *ppParams;
并访问pParam->name
,例如pParam[ii].name
。
访问(*ppParams)[ii]
您正在操纵单个API_AddParType
,但访问pParam[ii]
您正在操纵API_AddParType
数组。
答案 1 :(得分:1)
尝试更改行
API_AddParType* pParam = ppParams[ii];
到
API_AddParType* pParam = (*ppParams) + ii;
答案 2 :(得分:1)
在最后一种情况下,您将ppParams
视为指针数组,而不是指向数组的指针。
数组中的ii
:th元素在指针盒中以及其他情况下为(*ppParams)[ii]
。
你正在寻找它的地址,
API_AddParType* pParam = &(*ppParams)[ii];
或
API_AddParType* pParam = (*ppParams) + ii;
答案 3 :(得分:1)
下面的函数指向指向
的指针数组API_AddParType
结构
void ParamsListWrapper::ListParams2(API_AddParType** ppParams)
函数的参数是一个指向指针的指针 - API_AddParType
,它可以是指向API_AddParType
指针数组的第一个元素的指针,
ppParams
|
v
pParam0|pParam1|pParam2|...
| | | ...
v v v
xyz abc mno ...
或者它可以是一个指针(指向API_AddParType
数组的第一个元素的指针),
ppParams
|
v
pParams
|
v
param0|param1|param2|...
我将匿名内存位置ppParams
命名为pParams
(指向params的指针),以及函数接收指向pParams
而不是pParams
本身的指针的原因可能是指针pParams
本身可能被函数更改。
现在,在第一种情况下,(*ppParams)[ii] = pParam0[ii] = the object ii units after the start of xyz
,所以你永远不会看到pParam1
,pParam2
等指向的内容(除非这些指针设置为指向数组内部的数组)第一个元素pParam1
指向)。
在第二种情况下,(*ppParams)[ii] = pParams[ii] = the object ii units after the start of param0
,您按顺序查看所有整齐排列的paramN
。看起来不错。
使用
API_AddParType* pParam = ppParams[ii]
在第一种情况下,您会依次查看xyz
,abc
,mno
,...,看起来不错。
但在第二种情况下,pParam
将成为ii
之后的指针pParams
单位,但这不是指向API_AddParType
的指针数组的第一个元素。大小大于1,因此访问ppParams[ii]
是ii > 0
的未定义行为,并且因为API_AddParType
后面的pParams
不太可能存在有效指针,因此访问pParam->name
到pParam->value.real
resp。 ppParams[ii]
可能导致段错误。
您使用(*ppParams)[ii]
而非{{1}}的分段错误强烈暗示情况实际上是第二个,而不是第一个。