LINUX.ORG.RU

почему указатель на указатель и просто указатель имеют разные размеры

должны быть одинаковы. Указатель с плоской моделью памяти = адрес. 64х-битное адресное пространство = 64бит указатель=8 байт.

GAMer ★★★★★ ()
Ответ на: комментарий от X512

не не ребята...

дело в том что при переборе массива мне приходится шагать между указателями на указатель путем прибавления к ним 8 , но шараю между простыми указателями в той же программе на той же операционной системе путем прибавления 4

вопрос почему

Assembler ()
Ответ на: комментарий от anonymous

ну может так будет правильнее

почему у sizeof(int **) и sizeof (int *) разные размерности в одной и той же операционной системе?

Assembler ()
Ответ на: комментарий от X512

У него не система странная, у него выводы… эмм… алогичные ))

yyk ★★★★★ ()
Ответ на: комментарий от anonymous

тогда к второй части вопроса.

что я не так понимаю?

.section .text
.global foo
foo:


movq %rdi, %rbx; тут в %rbx  у меня адрес первого элемента  массива, который хранит указатели на другие указатели(ведь имя маассива -это указатель на его первый элемент). то есть в %rbx посути **P


в СИ чтобы перейти к следующему элементу массива указателей достаточно было сделать P+1

как я должен поступить тут? %rbx+8? %rbx+4?

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

в СИ чтобы перейти к следующему элементу достаточно было сделать P+1

В Си при прибавлении числа к указателю оно автоматически умножается на sizeof(<тип того, на что указывает указатель>).

как я должен поступить тут?

Зависит от того, из чего ваш массив. Если из указателей, то %rbx+8, если из int, то %rbx+4.

X512 ★★★★ ()
Ответ на: комментарий от Assembler

Потому что размеры указателя и int разные. sizeof(int) = 4 для GCC на x86_64.

X512 ★★★★ ()

Что бы сдвинуться на один элемент в массиве int нужно сдвинуться на один int, т.е. к указателю int* прибавить sizeof(int)==4 байт. Что бы сдвинуться в массиве int*, нужно изменить int** на sizeof(int*)==8 байт.

Marvel ()
Последнее исправление: Marvel (всего исправлений: 2 )
Ответ на: комментарий от Assembler

как я должен поступить тут? %rbx+8? %rbx+4?

rbx+<правильно определенная размерность твоих данных>. Любые циферки тут делают твой говнокод непереносимым и неподдерживаемым.

aalst ()
Ответ на: комментарий от aalst

можно подумать mov %rbx это дофига переносимо, лел

anonymous ()
Ответ на: комментарий от Marvel

огромное спасибо, что вы понимаете о чем вобще речь.

щас попытаюсь более конкретно спросить.

почему sizeof(int *)==8байт при том что sezeof(int)==4байта?

Assembler ()
Ответ на: комментарий от Assembler

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

anonymous ()
Ответ на: комментарий от Assembler

Потому что на твоей конкретной платформе указатель занимает 8 байт и выравнивается на них, а инт занимает 4 байта и выравнивается на них. Треду наоборот непонятно, откуда у тебя этот вопрос, ты бы шире что-ли задал его.

anonymous ()

указатель на указатель весит 8байт?

нет

Размерность указателя зависит от аппаратной реализации и реализации компилятора, закладывание на размерность указателя это минус переносимость кода и потенциальная ошибка. Если ты пишешь под определенную платформу, то плевать, если нет, то лучше так не делать. Это все что нужно знать, по большому счету, если тебя интересует именно на твоей платформе размер под указатель

  • к этому ты кажется не понимаешь что указатель == адрес, нет разницы какова вложенность указателя, даже указатель на указатель на указатель это просто один адрес, который ссылается на второй, который ссылается на третий.
anonymous ()
Ответ на: комментарий от anonymous

    int a[1][1] {{1}};
    int** a1 = (int** ) a;
    int* b = a[1];
    std::cout << "a " << a << "\n" << "b " << b  << "\n" << "a1 " << a1 << std:: endl;
    return 0;


a 0x780ede20f900 <--\
b 0x780ede20f904 <------ везде один адрес, но есть размерность не складывается
a1 0x780ede20f900 <-/



anonymous ()
Ответ на: комментарий от Assembler

почему sizeof(int *)==8байт при том что sezeof(int)==4байта?

Потому что sizeof(int*) тоже самое что sizeof(char*) и sizeof(void*) и любой иной указатель. И он показывает размер указателя который всегда один. А sezeof(int) показывает сколько занимает тип int

  • Указатель на что угодно всегда имеет 1 размер

  • Указатель на что угодно p* + n всегда значит что p* + (sizeof(type) * n) умножение на размер скрыто делая +1 ты прибавляешь размер данных через которые нужно перепрыгнуть.

LINUX-ORG-RU ★★★★★ ()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 2 )

LGH, когда твоего одногруппника уже отчислят? Пусть учится делать лабы сам, или хотя бы с помощью гугла.

Siborgium ★★★★ ()
Ответ на: комментарий от Assembler

потому что любой указатель это адрес, а адрес в x64 системах имеет размер 8 байт

хватит троллинг устраивать, сходите умные книжки почитайте или ютубик посмотрите

anonymous ()
Ответ на: комментарий от anonymous

да вот это я как раз и понимаю со слов здешних форумчан(уважаемых), что указатель на указатель -это адрес по которому лежит другой адрес. и именно поэтому мне неясно отчего это вдруг указатель на указатель типа int весит больше чем указатель int.


int ** == int *

тогда их размерности должны были бы быть равны.

Assembler ()
Ответ на: комментарий от Siborgium

да отчислили уже его. непереживайте.

вы забанили , а вам подобные преподы его из колледжа отчислили.

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

иначе я вынужден буду обратиться а жалобой. я нехочу тут слышать оскорбления и наблюдать флуд. нехотите помощь-выйдите. будьте добры.

Assembler ()
Ответ на: комментарий от Assembler

Они равны. Посмотри на их siZeof Ты про размеры значений или про размеры в памяти самих указателей или про размеры смещений при итерации? А то чёт я заподозрил ты имеешь в виду не то что говоришь

LINUX-ORG-RU ★★★★★ ()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 4 )
Ответ на: комментарий от Assembler

бесплатные уроки на лоре вместо прогулянных это похвально

но давайте вы будете самостоятельно обучаться

методом изучения соответствующих учебных материалов, а не троллингом на лорчике

anonymous ()
Ответ на: комментарий от Assembler

ну это где-то ты ошибся, они равны. Или это какая-то странная оптимизация реализации, но скорее все же ты ошибся с чем-то.

anonymous ()
Ответ на: комментарий от Siborgium

у него одногрупница

в соседних топиках про const набрасывает

тоже весь семестр на окружной работала

а теперь наверстывает

anonymous ()
Ответ на: комментарий от Assembler

Вот и славно. Годик походит в сапогах, потом на лету все схватывать будет.

Ответ на твой вопрос такой: int** и int* одинакового размера. Проблемы у тебя с пониманием концепта указателя и отличий в работе программы на С и ассемблере. Почитай про сложение указателя и числа в С и найди отличия от обычного сложения. Это даст тебе ответ на то, почему у тебя такие проблемы.

Siborgium ★★★★ ()
Ответ на: комментарий от LINUX-ORG-RU

ну хорошо.

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



}

я увеличил главную диагональ на 1 этой прогой.

Assembler ()
Ответ на: комментарий от Siborgium

насколько я знаю, он уехал в Китай.

если у вас есть хорошее понимание, и вы заявляете что int ** == int *

то я написал ниже пример своей программки для показа того, что это как -то не так. объясните.

Assembler ()
Ответ на: комментарий от Assembler

он ничего не обязан объяснять

идите к преподу или покупайте нужную лидерадуру и штудируйте

anonymous ()
Ответ на: комментарий от anonymous

вы правы. но тут уже иное. мы пытаемся выяснить где правда. уважаемый форумчанин сказал, что int** == int * равны.

я прошу его объяснить почему в таком случае на деле это не так.

это уже дело чести господа. все слова должны быть не пустыми.

Assembler ()
Ответ на: комментарий от Assembler

проф не пригодность должна быть отсеяна на ранних этапах

не надо затягивать с вступлением в ряды защитников родины

anonymous ()
Ответ на: комментарий от Assembler

шагаю от указателя ну указатель к другому указателю на указатель с шагом в 8 байт а ниже от указателя к указателю с шагом в 4 байта

:D Указатель это скалярный тип, всё верно. Бери листочек и бумажку, нарисуй блоки памяти по 1 байту и блоки по 4 байта и по 8, а теперь переходи по элементам этого массива и смотри какие значения при этом указатель имеет. Вот тут подсказка написана =)

ведь int** == int *

Всё верно

LINUX-ORG-RU ★★★★★ ()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3 )
Ответ на: комментарий от Assembler

правда в том что на лоре вам никто не обязан ничем

и так же не обязан говорить правду

вы ошибочно посчитали что кроме того что вас на лоре будут бесплатно учить

еще надеялись что вас будут учить правильно

лол

anonymous ()
Ответ на: комментарий от LINUX-ORG-RU

а причем тут значения?

от int ** к другому int ** я иду с шагом в 8байт

от int * к другому int * я иду с шагом в 4байта

если размеры их равны, то и там и там я должен идти или с шагом в 4байта или с шагом в 8байт.

но этого быть недолжно, если верить вашим словам

Assembler ()
Ответ на: комментарий от Assembler

призывник ассемблеров

не увиливайте от военкомата

постичь указатели вам не дано, примите и смиритесь

anonymous ()
Ответ на: комментарий от Assembler

Один не попал в предназначенное Родиной для него место, образовался недобор. Его предстоит восполнить вам.

Ответ я вам давать не буду, это нечестно по отношению к системе образования в целом и вашим одногруппникам в частности. Никакой чести в том, чтобы выпрашивать решение лабораторной на форуме я не вижу. Я указал, что вам нужно читать – читайте. Ответ там есть, вам нужно лишь открыть книгу/сайт. Более того, в комментариях выше это уже разжевали.

Дам еще одну подсказку: int* ничем не отличается от int** и от int*** и даже от std::string****** с точки зрения ассемблера.

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

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

ну что ж, спасибо в таком случае всем.

отдельное спасибо тем, кто не врал, а говорил искренне.

спасибо

Assembler ()
Ответ на: комментарий от Assembler

Вы переходите между int* и int, а не то, что вы написали. На сим я закругляюсь.

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