我有一个结构,这个结构的指针在main((中被mallocated,所以我可以制作一个结构的动态数组,我想使用这个函数填充数组:
void LoadData ( STRUCTURE ** str ){
所以我的问题是,当我使用这个概念时,为什么我的程序会抛出分段错误:
scanf( " %d", &str[i]->len )
当我使用时,一切都很好
scanf( " %d", &(*str)[i].len )
我认为(*str(.len相当于str->len。同样,这两种方法都适用于数组的第一个元素。提前谢谢。
正如您所描述的,在LoadData()
函数中,str
是指向标量的指针,而该标量恰好是另一个指针。因此,当i
不同于0时,str[i]
会产生越界数组访问,因为出于此目的,标量等效于单个元素数组。
另一方面,另一个指针*str
指向数组的第一个元素。因此,假设该数组包含n
元素,表达式(*str)[i]
访问0和n - 1
(包括0和10(之间的任何i
的有效数组元素(类型为STRUCTURE
(。因为它指定的是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)
。
您正确地认为(*str(.len等同于str->len(对于结构指针str(。但是,数组索引和成员访问具有相同的优先级,并且保持关联。因此,您的第一个示例被解释为
scanf( " %d", &((str[i])->len) )
而你的第二个例子被解释为
scanf( " %d", &(((*str)[i]).len) )
对所有内容都使用具体索引,第一个版本是写入str[i][0].len,而第二个版本则是写入str[0][i].len。