Имея это:
#include <stdio.h>
#include <stdlib.h>
struct Test { char c; } foo;
int main (void) {
struct Test **ar;
ar=malloc(16);
*(ar+1) = &foo;
ar[1]->c = 'c'; //this work
(*(*ar+1)).c = 'c'; //this does't work
return 0;
}
//(**(ar+1)).c='c'; --> first case
Почему вышеупомянутое работает только вариант с вводом в массив, а не разыменование указателя?
struct Test { char c; } foo;
int main (void) {
struct Test **ar;
ar=malloc(16);
*ar=malloc(0);
*(ar+1) = &foo;
//(**(ar+1)).c='c';
(*(*ar+1)).c='c'; // NOW IT WORKS --> second case
printf("%c\n", (*(*ar+1)).c); //prints 'c'
return 0;
}
Теперь даже выделено 0 байтов, это не имеет значения, так как я просто нужен адрес, предоставленный ОС, чтобы инициализировать первый элемент
вопрос: как работает арифметика указателя c в обоих случаях? Насколько я понимаю их:
1) сначала Чтобы получить lvalue struct Test
, указатель переходит непосредственно с указанного адреса ar
на lvalue **ar
- sizeof(struct Test**)
2) во втором случае указатель инициализировал первый член ar[0]
, поэтому он начинается здесь *ar
и переходит к lvalue на *ar
- sizeof(struct Test*)
.
Но оба указателя имеют одинаковый размер sizeof(struct Test**) == sizeof(struct Test*)
, и поэтому не должно быть разницы в арифметических c, иначе мне что-то не хватает?