使用指针而不是引用时访问指向结构的指针数组时出现段错误
Got segfault accessing array of pointers to struct when using pointers instead of references
下面的函数获取指向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" );
}
}
}
出现分段错误。怎么可能?为什么在引用工作没有任何问题时通过指针访问数据时会失败?
下面的函数将指针指向指向
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|...
我在哪里命名了指向pParams
的匿名内存位置ppParams
(指向参数的指针),函数接收指向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
将成为pParams
之后的指针ii
单位,但这不是指向大小大于 1 的指针数组中的第一个元素API_AddParType
,因此访问ppParams[ii]
对于ii > 0
来说是未定义的行为,并且由于不太可能碰巧有有效的指针指向API_AddParType
就在pParams
后面, 访问pParam->name
pParam->value.real
可能会导致段错误。
事实上,你得到了一个分割错误ppParams[ii]
,而不是(*ppParams)[ii]
,这强烈暗示这种情况实际上是第二种,而不是第一种。
尝试将API_AddParType* pParam = ppParams[ii];
更改为API_AddParType* pParam = *ppParams;
并访问pParam->name
,如下所示pParam[ii].name
。
通过访问(*ppParams)[ii]
您正在操纵单个API_AddParType
,但访问pParam[ii]
您正在操作一系列API_AddParType
。
尝试更改行
API_AddParType* pParam = ppParams[ii];
自
API_AddParType* pParam = (*ppParams) + ii;
在最后一种情况下,您将ppParams
视为指针数组,而不是指向数组的指针。
数组的ii
:th 元素在指针大小写和其他情况下都(*ppParams)[ii]
。
您正在寻找它的地址,即
API_AddParType* pParam = &(*ppParams)[ii];
或
API_AddParType* pParam = (*ppParams) + ii;
- 指向指向字符数组的指针数组的指针
- 通过指向指针数组的指针访问子类的属性
- C++,指针数组,指向双链表中的条目
- 在C++中,如何初始化指向wchar_t*的指针数组(生成wchar_t**)
- C++从函数指针数组调用函数
- 关于指向指针数组的指针
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 将链表转换为指针数组时出错
- C++ 对象指针数组的复制构造函数
- C++ - 循环访问指针数组会导致错误
- 删除指针数组 (C++) 中的元素
- 如何循环访问 cpp 中的函数返回的字符指针数组
- 将函数指针数组中的函数指针作为模板参数传递
- Google Or-Tools Glop:如何创建指向 const 对象的指针数组?
- 具有推导参数的模板函数指针数组变量
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- C++指针数组到字符数组中的特定位置
- 如何在C++中复制指针数组的数据
- 初始化类中的指针数组,并在另一个类中检索它
- 尽管直接设置了指针数组,但仍为空