0

下面的函数接受一个指向结构指针数组的指针,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" );
        }
    }
}

出现分段错误。怎么会这样?为什么通过指针访问数据时它会失败,而引用工作没有任何问题?

4

4 回答 4

1

尝试像这样API_AddParType* pParam = ppParams[ii];更改API_AddParType* pParam = *ppParams;和访问。pParam->namepParam[ii].name

通过访问(*ppParams)[ii]您正在操作单个API_AddParType,但访问pParam[ii]您正在操作一个 . 数组API_AddParType

于 2012-10-04T12:24:52.003 回答
1

换行试试

API_AddParType* pParam = ppParams[ii];

API_AddParType* pParam = (*ppParams) + ii;
于 2012-10-04T12:32:26.673 回答
1

在最后一种情况下,您将ppParams其视为指针数组,而不是指向数组的指针。

数组的ii:th 元素(*ppParams)[ii]在指针的情况下以及在其他情况下。
您正在寻找它的地址,即

API_AddParType* pParam = &(*ppParams)[ii];

或者

API_AddParType* pParam = (*ppParams) + ii;
于 2012-10-04T14:05:09.640 回答
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(指向参数的指针),函数接收指向pParams而不是pParams自身的指针的原因可能是指针pParams本身可能被函数更改。

现在,在第一种情况下,(*ppParams)[ii] = pParam0[ii] = the object ii units after the start of xyz, 所以你永远不会看pParam1, pParam2etc. 指向什么(除非这些指针被设置为指向第一个元素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之后的指针单元,但这不是大小大于 1pParams的指针数组的第一个元素,因此访问对于 来说是未定义的行为,并且由于不太可能发生有效指向后面的指针,访问相应的。可能会导致段错误。API_AddParTypeppParams[ii]ii > 0API_AddParTypepParamspParam->namepParam->value.real

您遇到分段错误的事实ppParams[ii],但没有(*ppParams)[ii]强烈暗示这种情况实际上是第二个,而不是第一个。

于 2012-10-04T14:05:59.657 回答