Массив структур, переданных в функцию, различие различий между -> и * - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть структура, указатель на эту структуру неправильно расположен в main (), поэтому я могу создать динамический массив структур и хочу заполнить массив с помощью этой функции:

void LoadData ( STRUCTURE ** str ){

Так что мойвопрос в том, почему моя программа выдает ошибку сегментации, когда я использую это понятие:

           scanf( " %d", &str[i]->len ) 

И все работает просто отлично, когда я использую это:

           scanf( " %d", &(*str)[i].len )

Я думал, что (* str).len эквивалентно str-> len.Также оба работают для 1-го элемента массива.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 05 декабря 2018

Как вы это описали, в вашей функции LoadData(), str - это указатель на скаляр, который является другим указателем.str[i], следовательно, создает доступ к массиву вне границ, когда i отличается от 0, поскольку для этой цели скаляр эквивалентен одноэлементному массиву.

С другой стороны, *str, другой указатель, указывает на первый элемент массива.Предполагая, что этот массив содержит n элементов, следовательно, выражение (*str)[i] обращается к допустимому элементу массива (типа STRUCTURE) для любого i в диапазоне от 0 до 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).

0 голосов
/ 05 декабря 2018

Вы правы, что (* str) .len эквивалентно str-> len (для указателя структуры str).Однако индексирование массива и доступ к элементу имеют одинаковый приоритет и являются левоассоциативными.В результате ваш первый пример интерпретируется как

scanf( " %d", &((str[i])->len) )

, тогда как ваш второй пример интерпретируется как

scanf( " %d", &(((*str)[i]).len) )

Используя конкретные индексы для всего, первая версия записывает в str [i] [0] .len, тогда как второй пишет в str [0] [i] .len.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...