LINUX.ORG.RU

Приключения в стране указателей

 


0

1

Вопрос наверняка весьма нубский в области С. Проблема возникла с указателями на указатели структур. Если мы рассмотрим такой код:

struct tests
{
int i;
int j;
};
void change(struct tests **a);

int main()
{
struct tests* a;
change(&a);
}

void change(struct tests **a)
{
*a=(struct tests *)malloc(sizeof(struct tests));

**a->i=1;
**a->j=2;
}

То он будет вызывать ошибку компиляции:

  
error: request for member ‘i’ in something not a structure or union
error: request for member ‘j’ in something not a structure or union

В то же время такой код функции не будет:

 *a=(struct tests *)malloc(sizeof(struct tests));
struct tests temp;
temp.i=2;
temp.j=1;
**a=temp; 

Насколько я понимаю объясняется такое различие тем что сам указатель не организует участок памяти в структуру, а только дает адрес куда ее сохранить. Временная переменная и есть то что сохранятся в ячейку памяти с адресом в указателе.

Однако не совсем тогда понятно почему работает вполне корректно такая программа:


#include<stdio.h>
#include<stdlib.h>
void change(int **a);
int main()
{
int* a;
a=NULL;
change(&a);
printf("%d\n",*a);
return 0;
}

void change(int **a)
{
*a=(int*)malloc(sizeof(int));
**a=8;
}

★★★★★

Последнее исправление: cetjs2 (всего исправлений: 1)
Ответ на: комментарий от pylin

Смотри, как анонимус написал. Одна звёздочка. Но с учётом приоритетности операций, видимо.

post-factum ★★★★★
()
$ cat main.c 
#include <stdio.h>
#include <stdlib.h>
typedef struct tests
{
  int i;
  int j;
} tests;
void change(tests **a);
int main()
{
  tests* a;
  change(&a);
  printf("a->i=%i\n",a->i);
  printf("a->j=%i\n",a->j);
}
void change(tests **a)
{
  *a=(tests *)malloc(sizeof(tests));
  (*a)->i=1;
  (*a)->j=2;
}
$ gcc main.c 
$ ./a.out 
a->i=1
a->j=2
anonymous
()

Пример анонима разъяснил ситуацию.

pylin ★★★★★
() автор топика
Ответ на: комментарий от post-factum

Я как-то странно скобки ставил, в общем чудить начал, всем участвовавшим в ликбезе спасибо.

pylin ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.