Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.07.2017, 21:39   #1
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию return адрес

Хочу написать ф-цию, которая бы возвращала в main адрес переменной, хранящей char, но ничего не выходит: чтобы ни пробовал - все время выводит 0 или ошибку.

PS пробовал выводимое значение ставить long и char + указатель на ф-ции
tutejshy вне форума Ответить с цитированием
Старый 06.07.2017, 21:46   #2
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

показывайте код, телепаты в отпуске.
alexzk вне форума Ответить с цитированием
Старый 06.07.2017, 21:48   #3
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Код:
char ch = 'h';
char* addr = &ch;
printf("%p", (void*) addr);
А функция-то причем тут?
Если ошибка при попытке разыменовать указатель указывающий непонятно куда, то ничего удивительного.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 06.07.2017 в 21:50.
Alex11223 вне форума Ответить с цитированием
Старый 06.07.2017, 21:57   #4
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию

Ещё раз: нужна ф-ция, которая возвращает адрес! Зачем ты пишешь мне этот код?

нужно что-то типа того:
Код:
long f-ci (void)
{
      char a = 1;
      return &a;
}
int main (void)
{
     printf ("%x\n", f-ci());//сдесь вроде как доджен отобразится адрес пременной а
     return 0;
}
как-то вот так, но, конечно, не работает - хочу понять как сделать правильно
tutejshy вне форума Ответить с цитированием
Старый 06.07.2017, 22:06   #5
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от tutejshy Посмотреть сообщение
Ещё раз: нужна ф-ция, которая возвращает адрес! Зачем ты пишешь мне этот код?

нужно что-то типа того:
Код:
long f-ci (void)
{
      char a = 1;
      return &a;
}
как-то вот так, но, конечно, не работает - хочу понять как сделать правильно

Так оно и не будет работать, потому что char a существует ТОЛЬКО внутри функции (на стеке!!!!) по завершении - стек откатывается в исходное состояние и там мусор.

Код:
long fci (void)
{
      static char a = 1;
      return &a;
}
int main (void)
{
     printf ("%x\n", fci());//сдесь вроде как доджен отобразится адрес пременной а
     return 0;
}
можно сделать вот так, НО - запись статик означает, что строка static char a = 1; исполнится всего 1 раз за все время жизни программы. Более того значение такой a, доступное любым способом, будет общим. Т.е. фактически этот кусок памяти будет создан при старте и удален в конце - он будет всегда одно и тоже. Вобщем вернее было бы так

Код:
long fci (void)
{
      return new char[1];
}
int main (void)
{
    char * a = fci(); 
    printf ("%x\n", a);//сдесь вроде как доджен отобразится адрес пременной а
    delete []a;
     return 0;
}
Здесь создаем память уже в "куче", и не забываем ее удалять, когда она уже не нужна. Причем обратите внимани на формат удаления [] (т.к. создавали массив [1], то и удаляем массив delete [])



Кстати, это тоже не совсем верно
printf ("%x\n", a);//сдесь вроде как доджен отобразится адрес пременной а

В частности, под МС-ДОС будут чудные баги.
Т.к. указатель это не всегда гарантировано целое число (на нек. системах это пара чисел).




Ах, ну я еще не обратил внимание, что у вас там результат функции long везде... это тоже не верно, компилер будет ругаться, по причине, что указатель не всегда число. Более того, long не всегда 64 бита, тогда как на 64 бит системе указатель будет строго 64 бит. Вопщем предлагаю это обдумать самостоятельно.

Вопщем нарушено все, что можно нарушить в коде.

Последний раз редактировалось alexzk; 06.07.2017 в 22:17.
alexzk вне форума Ответить с цитированием
Старый 06.07.2017, 22:17   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Так автор же просто адрес получить хотел, а не разыменовывать его.
А получил 0.

В VS и clang кстати не 0, может это оптимизация какая-то? Или UB.

http://rextester.com/PBHLK89432
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 06.07.2017, 22:20   #7
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Так автор же просто адрес получить хотел, а не разыменовывать его.
А получил 0.

В VS и clang кстати не 0, может это оптимизация какая-то? Или UB.

http://rextester.com/PBHLK89432
Да я там дописал уже, надоело править ) сразу не обратил внимание, что результат long. Он может быть равен указателю только на 32 бита винде. В остальных случаях, там ХЗ просто.

Вон у меня в CURL long на линухе 64 бита, на маке 32 бита (а мак 64 сам), потому что по умолчанию собирает под старые системы.... Пришлось флаги добавлять и проверки.

Вообще, size_t равен указателю обычно, т.е. почти переносимо так:


Код:
size_t f-ci (void)
{
      char a = 1;
      return static_cast<size_t>(&a); //или reinterpret_cast
}
Но это именно что почти, если у проца сегментная модель - такое не взлетит.

Последний раз редактировалось alexzk; 06.07.2017 в 22:25.
alexzk вне форума Ответить с цитированием
Старый 06.07.2017, 22:23   #8
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Ну с char* тоже:
http://rextester.com/CWHB98074
http://rextester.com/ZEJQ50304
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 06.07.2017, 22:31   #9
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Код:
//gcc 5.4.0

#include  <stdio.h>

size_t f(void)
{
      char a = 1;
      size_t v = &a;
      return v;
}
int main (void)
{
     printf ("%lx\n", f());//сдесь вроде как доджен отобразится адрес пременной а
     return 0;
}
Так работает.

Код:
//gcc 5.4.0

#include  <stdio.h>

size_t f(void)
{
      static char a = 1;
       
      return (size_t)&a;
}
int main (void)
{
     printf ("%lx\n", f());//сдесь вроде как доджен отобразится адрес пременной а
     return 0;
}
Так тоже работает, а иначе справедливо все оптимизируется к черту, вместе с вызовом функции. Компилер полагает, что раз там ниче не делается, то адрес локальной переменной NULL (а чтоб упало и программер заметил).
alexzk вне форума Ответить с цитированием
Старый 09.07.2017, 09:41   #10
tutejshy
Форумчанин
 
Регистрация: 13.05.2017
Сообщений: 100
По умолчанию

Цитата:
Да я там дописал уже, надоело править ) сразу не обратил внимание, что результат long. Он может быть равен указателю только на 32 бита винде. В остальных случаях, там ХЗ просто.
long на Windows 32 бита, а на Unix 64 бита, размер указателя тоже варьируется: 4 байта для 32 и 8 для 64 - так ведь?

PS. Спасибо за инфу по проблеме, особенно про работу в других компиляторах.

Последний раз редактировалось tutejshy; 09.07.2017 в 09:44.
tutejshy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Return; Мой повелитель Общие вопросы C/C++ 1 13.06.2016 17:25
Оператор "return" без значения. функции оператора "return" Алексей111083 Помощь студентам 1 17.01.2016 17:18
c++, return nastya8289 Помощь студентам 1 12.11.2015 20:56
Как подменить адрес возврата функции func на адрес функции f используя переполнение буфера buf и функции gets dmitrii6120 Помощь студентам 6 14.11.2011 20:10
как узнать ip адрес зная mac адрес Roman Работа с сетью в Delphi 9 25.06.2007 12:39