Гость Опубликовано 24 февраля, 2002 Жалоба Поделиться Опубликовано 24 февраля, 2002 Люди, подскажите, пжалста!!! Вот пример проги с void.ru: void function(int a, int b, int c) { char buffer1[5]; char buffer2[15]; int *ret; ret = buffer1 + 12; /* прога отлично "работает" на gcc-2.95.3 (под FreeBSD) и на kgcc-2.91.66 (egcs под Linux-2.4.16), но под gcc-2.96 */ // ret = buffer1 + 28; // <-- приходится делать так... (*ret) += 8; //(*ret) += 10; // и так void main() { int x; x = 0; function(1, 2, 3); x = 1; printf("%d\n",x); } В чем дело? Что еще запихивается в стек до buffer1, или там выравнивание проискодит по другому? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 25 февраля, 2002 Жалоба Поделиться Опубликовано 25 февраля, 2002 nu vo pervih, void main() --> eto ploho. pochemu? : smotri http://www.faqs.org/faqs/C-faq/faq/ vtoroe, ret eto ukazatel'. buffer1 --> eto massiv. buffer1 --> facticheski buffer1[0]; tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu ugodno. takim obrazom, ret = buffer1 + 12; zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). neudivitel'no shto inogda ret pokazivaet kuda to, a inogda i za predeli. otsyuda i SIGSEGV. krome togo, ret obyavlen ukazatelen typa int., a pokazivaet na char. navernoe hotelos' sdelat' shto-to typa: char buffer1[5]; char *ret = NULL; ret = &buffer1 + 12; odnako, 12 sovershenno ne garantiruet 12 elementov.) sovershenno verno bilo zamecheno, shto viravnivanie mozet proishodit.... pravilv'no bilo bi shto to typa: ret = &buffer1; ret += (12*sizeof(buffer1[0])); Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 25 февраля, 2002 Жалоба Поделиться Опубликовано 25 февраля, 2002 сделал вместо weekly daily... На следующий день висят оба процесса logrotate - за вчера (висит без остановки); - за наступивший день. Через неделю их будет семь... Пробовал переносить логи на время в другое место - все равно висят. В общем, бред...> ret eto ukazatel'. Точнее в стеке хранится адрес возврата > buffer1 --> facticheski buffer1[0]; buffer1 == &buffer1[0] > tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu > ugodno. kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя это проверяется командой kgcc -S ex.c (получится асмовский код) А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт.... > takim obrazom, ret = buffer1 + 12; > zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл. > navernoe hotelos' sdelat' shto-to typa: > char Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 25 февраля, 2002 Жалоба Поделиться Опубликовано 25 февраля, 2002 > ret eto ukazatel'. Точнее в стеке хранится адрес возврата > buffer1 --> facticheski buffer1[0]; buffer1 == &buffer1[0] > tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu > ugodno. kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя это проверяется командой kgcc -S ex.c (получится асмовский код) А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт.... > takim obrazom, ret = buffer1 + 12; > zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл. > navernoe hotelos' sdelat' shto-to typa: > char buffer1[5]; > char *ret = NULL; > ret = &buffer1 + 12; 1) ret = buffer1 + 12; 2) тут действует стандартное преобразование типов. Фактически: buffer1 = buffer1 + 12; ret = buffer1; --------------------- Так все таки почему gcc-2.96 отводит "левое" кол-во памяти??? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 25 февраля, 2002 Жалоба Поделиться Опубликовано 25 февраля, 2002 > ret eto ukazatel'. Точнее в стеке хранится адрес возврата > buffer1 --> facticheski buffer1[0]; buffer1 == &buffer1[0] > tak kak buffer1[] ne inizializirovan, buffer1[0] == chemu > ugodno. kgcc выделяет память под char buffer1[5], buffer2[10] и int *ret в стеке: "subl $28,%esp" с учетом сохранения стекового указателя это проверяется командой kgcc -S ex.c (получится асмовский код) А gcc-2.96 выделяет 56 байт в стеке ,причем, если добавить char buffer3[20], то будет выделено 88 байт.... > takim obrazom, ret = buffer1 + 12; > zastavlyaet pokazivat' ret sluchainim obrazom v nikuda(?). Не в никуда, а в конкретную ячейку стека (в нашем случае в ней хранится адрес возврата). И на других компиляторах все отлично работает! ВСЕГДА. На gcc-2.96 тоже всегда, но с другим смещенем. А что бы узнать это "другое" смещение нужно уже лезть в асм-файл. > navernoe hotelos' sdelat' shto-to typa: > char buffer1[5]; > char *ret = NULL; > ret = &buffer1 + 12; 1) ret = buffer1 + 12; 2) тут действует стандартное преобразование типов. Фактически: buffer1 = buffer1 + 12; ret = buffer1; --------------------- Так все таки почему gcc-2.96 отводит "левое" кол-во памяти??? Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 25 февраля, 2002 Жалоба Поделиться Опубликовано 25 февраля, 2002 в gdb набери help stack и не морочь людям голову Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Гость Опубликовано 26 февраля, 2002 Жалоба Поделиться Опубликовано 26 февраля, 2002 Вообще-то, чтобы получить return address в gcc есть __builtin_return_address..... А для того чтобы делать нелокальные переходы вообще-то лучше setjmp/longjmp Цитата Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.