дело в том что при переборе массива мне приходится шагать между указателями на указатель путем прибавления к ним 8 , но шараю между простыми указателями в той же программе на той же операционной системе путем прибавления 4
.section .text
.global foo
foo:
movq %rdi, %rbx; тут в %rbx у меня адрес первого элемента массива, который хранит указатели на другие указатели(ведь имя маассива -это указатель на его первый элемент). то есть в %rbx посути **P
в СИ чтобы перейти к следующему элементу массива указателей достаточно было сделать P+1
Что бы сдвинуться на один элемент в массиве int нужно сдвинуться на один int, т.е. к указателю int* прибавить sizeof(int)==4 байт. Что бы сдвинуться в массиве int*, нужно изменить int** на sizeof(int*)==8 байт.
Потому что на твоей конкретной платформе указатель занимает 8 байт и выравнивается на них, а инт занимает 4 байта и выравнивается на них. Треду наоборот непонятно, откуда у тебя этот вопрос, ты бы шире что-ли задал его.
Размерность указателя зависит от аппаратной реализации и реализации компилятора, закладывание на размерность указателя это минус переносимость кода и потенциальная ошибка. Если ты пишешь под определенную платформу, то плевать, если нет, то лучше так не делать. Это все что нужно знать, по большому счету, если тебя интересует именно на твоей платформе размер под указатель
к этому ты кажется не понимаешь что указатель == адрес, нет разницы какова вложенность указателя, даже указатель на указатель на указатель это просто один адрес, который ссылается на второй, который ссылается на третий.
почему sizeof(int *)==8байт при том что sezeof(int)==4байта?
Потому что sizeof(int*) тоже самое что sizeof(char*) и sizeof(void*) и любой иной указатель. И он показывает размер указателя который всегда один. А sezeof(int) показывает сколько занимает тип int
Указатель на что угодно всегда имеет 1 размер
Указатель на что угодно p* + n всегда значит что p* + (sizeof(type) * n) умножение на размер скрыто делая +1 ты прибавляешь размер данных через которые нужно перепрыгнуть.
да вот это я как раз и понимаю со слов здешних форумчан(уважаемых), что указатель на указатель -это адрес по которому лежит другой адрес.
и именно поэтому мне неясно отчего это вдруг указатель на указатель типа int весит больше чем указатель int.
Они равны. Посмотри на их siZeof Ты про размеры значений или про размеры в памяти самих указателей или про размеры смещений при итерации? А то чёт я заподозрил ты имеешь в виду не то что говоришь
Вот и славно. Годик походит в сапогах, потом на лету все схватывать будет.
Ответ на твой вопрос такой: int** и int* одинакового размера. Проблемы у тебя с пониманием концепта указателя и отличий в работе программы на С и ассемблере. Почитай про сложение указателя и числа в С и найди отличия от обычного сложения. Это даст тебе ответ на то, почему у тебя такие проблемы.
int main(){
extern void foo(int** P);
int **P;
P=(int **)malloc(3*sizeof(int*));
*P=(int* ) malloc(3*sizeof(int));
*(P+1)=(int*)malloc(3*sizeof(int));
*(P+2)=(int*)malloc(3*sezeof(int));
*(*P)=1;
*(*P)=2;
*(*P)=3;
*(*(P+1))=4;
*(*(P+1)+1)=5;
*(*(P+1)+2)=6;
*(*(P+2))=7;
*(*(P+2)+1)=8;
*(*(P+2)+2)=9;
foo(P);
.section .text
.global foo
foo:
push %rbp
movq %rsp, %rbp
movq %rdi, %r9
mov $0, -8(%rbp)
jmp two:
one:
mov(%r9), %rax
add %rbx, %rax
add $1, (%rax)
add $8, %r9; вот тут я шагаю от указателя ну указатель к другому указателю на указатель с шагом в 8 байт. а ниже от указателя к указателю с шагом в 4 байта. ведь int** == int *
add $4, %rbx; почему тут я шагую от указателя к указателю с шагом в 4байта а выше с шаго в 8 байт?
add $1, -8(%rbp)
two:
cmp $2, -8(%rbp)
jle one
leave
ret
}
шагаю от указателя ну указатель к другому указателю на указатель с шагом в 8 байт
а ниже от указателя к указателю с шагом в 4 байта
:D Указатель это скалярный тип, всё верно. Бери листочек и бумажку, нарисуй блоки памяти по 1 байту и блоки по 4 байта и по 8, а теперь переходи по элементам этого массива и смотри какие значения при этом указатель имеет. Вот тут подсказка написана =)
Один не попал в предназначенное Родиной для него место, образовался недобор. Его предстоит восполнить вам.
Ответ я вам давать не буду, это нечестно по отношению к системе образования в целом и вашим одногруппникам в частности. Никакой чести в том, чтобы выпрашивать решение лабораторной на форуме я не вижу. Я указал, что вам нужно читать – читайте. Ответ там есть, вам нужно лишь открыть книгу/сайт. Более того, в комментариях выше это уже разжевали.
Дам еще одну подсказку: int* ничем не отличается от int** и от int*** и даже от std::string****** с точки зрения ассемблера.
Берите карандаш, рисуйте, как вам посоветовали. Если вы понимаете, как работает адресация, то вы мгновенно получите ответ на свой вопрос. Если вы этого не понимаете, то я искренне не понимаю, почему вы должны получить зачет.