我有一个结构,在main()中分配了该结构的指针,因此我可以创建一个动态的结构数组,并且想使用此函数填充该数组:
void LoadData ( STRUCTURE ** str ){
所以我的问题是为什么当我使用此概念时,我的程序为什么会引发分段错误:
scanf( " %d", &str[i]->len )
当我使用这个时一切都很好:
scanf( " %d", &(*str)[i].len )
我认为(* str).len等同于str-> len。 两者都适用于数组的第一个元素。预先感谢。
答案 0 :(得分:3)
正如您所描述的,在LoadData()
函数中,str
是指向标量的指针,该标量恰好是另一个指针。因此,str[i]
在i
不同于0时会产生越界数组访问,因为为此目的,标量等效于单元素数组。
另一方面,另一个指针*str
指向数组的第一个元素。假设该数组包含n
个元素,因此,表达式(*str)[i]
为0到STRUCTURE
之间的任何i
访问一个有效的数组元素(类型为n - 1
) , 包括的。因为那是指定STRUCTURE
,而不是STRUCTURE *
,所以您必须通过.
运算符而不是通过->
访问其成员。
要更清楚地看到两个表达式不同,让我们根据标识a[b] == *((a) + (b))
和p->x == (*p).x
对其进行转换。一方面,我们有
&str[i]->len == &(str[i]->len)
== &((*str[i]).len)
== &((**(str + i)).len)
另一方面,我们有
&(*str)[i].len == &(((*str)[i])).len)
== &((*(*str + i)).len)
。请注意,**(str + i)
不等于*(*str + i)
。
答案 1 :(得分:2)
您正确的认为(* str).len与str-> len等效(对于结构指针str)。但是,数组索引和成员访问都具有相同的优先级并且是左关联的。结果,您的第一个示例被解释为
scanf( " %d", &((str[i])->len) )
第二个示例解释为
scanf( " %d", &(((*str)[i]).len) )
使用所有内容的具体索引,第一个版本写入str [i] [0] .len,而第二个版本写入str [0] [i] .len。