Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
0 / 0 / 0
Регистрация: 24.02.2018
Сообщений: 23

Некорректно работают указатели на функцию

25.03.2018, 01:27. Показов 3422. Ответов 73
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В режиме отладки видно что, функция возвращает правильный результат, но на экран выводится какой-то мусор.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <conio.h>
 
using namespace std;
 
int* a()
{
    int b[] = { 1,2,3 };
    return b;
}
 
int main()
{
    setlocale(LC_ALL, "Russian");
 
    int *ar;
    ar = a();
    
    cout << ar[0] << ar[1] << ar[2];
 
    _getch();
    return 0;
}
Почему так происходит? Как это исправить? Как это работает?
Миниатюры
Некорректно работают указатели на функцию   Некорректно работают указатели на функцию   Некорректно работают указатели на функцию  

Некорректно работают указатели на функцию   Некорректно работают указатели на функцию   Некорректно работают указатели на функцию  

0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
25.03.2018, 01:27
Ответы с готовыми решениями:

некорректно работают условия
#include &quot;stdafx.h&quot; #include &quot;stdio.h&quot; #include &quot;locale&quot; #include &quot;stdlib.h&quot; int main() { int q; float a, b, r; ...

2 функции по перестановке векторов работают некорректно
Написал 2 функции по перестановки векторов, они делают свою работы, но не так как нужно. В начале пявляеться набор чисел, а если запускать...

Не работают указатели
Как сделать указатели на функцию в моем случае? много чего перепробовал, ничего не работает. помогите пжлста. #include...

73
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 01:38
Цитата Сообщение от VibeProgramm Посмотреть сообщение
Некорректно работают указатели на функцию
1. у вас там просто на дух нет "указателя на функцию" ... от слова "совсем".
Цитата Сообщение от VibeProgramm Посмотреть сообщение
Code
1
int b[] = { 1,2,3 };
2. это локальная переменная, после возврата из функции она уже уничтожена (занимаемая ею память уже использована под что-то ещё полезное).
1
475 / 427 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
25.03.2018, 01:44
Лучший ответ Сообщение было отмечено VibeProgramm как решение

Решение

Время жизни статик массива ограничено функцией. Объявляйте внутри функции динамический массив.
Однако:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int* a()
{
    int b[3] = { 1,2,3 };
    return b;
}
 
int* a()
{
    int *b = new int{1,2,3};
    return b;
}
 
int* a()
{
    int b[3] = { 1,2,3 };
    return *&b;
}
 
int* a()
{
    int *b = new int[3]{ 1,2,3 };
    return *&b;
}
Лично у меня любой из этих вариантов выводит то, что надо.
1
0 / 0 / 0
Регистрация: 24.02.2018
Сообщений: 23
25.03.2018, 01:46  [ТС]
Цитата Сообщение от Olej Посмотреть сообщение
у вас там просто на дух нет "указателя на функцию" ... от слова "совсем".
Да действительно напутал извиняюсь
Цитата Сообщение от Olej Посмотреть сообщение
2. это локальная переменная, после возврата из функции она уже уничтожена (занимаемая ею память уже использована под что-то ещё полезное).
Да вроде все так, но смотрю чувака на ютубе, у него все работает почему-то. Почему у него работает, а у меня нет?
Миниатюры
Некорректно работают указатели на функцию  
0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 01:50
Цитата Сообщение от VibeProgramm Посмотреть сообщение
Да вроде все так, но смотрю чувака на ютубе, у него все работает почему-то.
Не надо смотреть чуваков на ютубе - чуваки на ютубе до добра не доведут!
1
Любитель чаепитий
 Аватар для GbaLog-
3745 / 1801 / 566
Регистрация: 24.08.2014
Сообщений: 6,020
Записей в блоге: 1
25.03.2018, 01:55
Цитата Сообщение от VibeProgramm Посмотреть сообщение
Почему у него работает, а у меня нет?
так сошлись звёзды.
Цитата Сообщение от VibeProgramm Посмотреть сообщение
смотрю чувака на ютубе
таких лучше не смотреть.
0
0 / 0 / 0
Регистрация: 24.02.2018
Сообщений: 23
25.03.2018, 02:00  [ТС]
Цитата Сообщение от SuperKir Посмотреть сообщение
int* a()
{
* * int *b = new int[3]{ 1,2,3 };
* * return *&b;
}
У меня вот это заработало. А что означает
C++
1
 return *&b;
?

Цитата Сообщение от Olej Посмотреть сообщение
Не надо смотреть чуваков на ютубе - чуваки на ютубе до добра не доведут!
Мне просто по видео проще обучаться ...
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,113
25.03.2018, 02:03
Цитата Сообщение от VibeProgramm Посмотреть сообщение
Да вроде все так, но смотрю чувака на ютубе, у него все работает почему-то. Почему у него работает, а у меня нет?
Возможно всё дело в различных опциях компиляции. В общем случае так делать нельзя, это ошибка.
Для понимания причин нужно немного узнать про исполнение программы на более низком уровне: что такое регистры, как организуется вызов функций и передача их аргументов, как работает стек и где размещаются локальные переменные. В двух словах это не объяснить, проще сказать, что так делать не нужно)
1
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
25.03.2018, 02:06
Цитата Сообщение от VibeProgramm Посмотреть сообщение
C++
1
2
3
4
5
int* a()
{
    int b[] = { 1,2,3 };
    return b;
}
C++
1
2
3
4
5
int* a()
{
    static int b[] = { 1,2,3 };
    return b;
}
0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 02:10
Цитата Сообщение от SuperKir Посмотреть сообщение
Лично у меня любой из этих вариантов выводит то, что надо.
1) и 3) - глупость какая!

Добавлено через 1 минуту
Цитата Сообщение от VibeProgramm Посмотреть сообщение
Мне просто по видео проще обучаться ...
В общественных сортирах тоже много чего пишут пальцем на стене...

Добавлено через 1 минуту
Цитата Сообщение от Ygg Посмотреть сообщение
Возможно всё дело в различных опциях компиляции
Никакие опции здесь не при чём и не помогут.
0
475 / 427 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
25.03.2018, 02:10
Olej, интересно то, что эта глупость работает) а как - еще интереснее
0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 02:12
Цитата Сообщение от VibeProgramm Посмотреть сообщение
У меня вот это заработало.
Только потому что там new. Но вы ещё задумайтесь: когда вы для него delete[] станете делать?

Цитата Сообщение от VibeProgramm Посмотреть сообщение
А что означает?
Code
1
return *&b;
Да так ... онанизм
0
475 / 427 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
25.03.2018, 02:12
Цитата Сообщение от VibeProgramm Посмотреть сообщение
А что означает
*& - это ссылка на указатель.

А использовать лучше:
C++
1
2
3
4
5
int* a()
{
    int *b = new int[3]{ 1,2,3 };
    return b;
}
1
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 02:14
Цитата Сообщение от SuperKir Посмотреть сообщение
интересно то, что эта глупость работает)
Не работает
Не надо ля-ля о том, чего ни хера не понимаете, дружище.
А что "работает" - так то показалось.
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
25.03.2018, 02:18
Цитата Сообщение от SuperKir Посмотреть сообщение
*& - это ссылка на указатель.
Разве?
0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 02:20
Цитата Сообщение от SuperKir Посмотреть сообщение
А использовать лучше:
Ничего не "лучше"!
Потому что память под переменную выделяется внутри функции, а освобождать/удалять её нужно где-то в вызывающем коде, и не забыть это сделать.
Лучшее из всего, что пЫАнЭры здесь напредлагали, если совсем уж без такой конструкции как возврат массива из функции нельзя обойтись, то это объявить этот массив внутри функции static.
0
2735 / 890 / 331
Регистрация: 10.02.2018
Сообщений: 2,113
25.03.2018, 02:26
Цитата Сообщение от Olej Посмотреть сообщение
Никакие опции здесь не при чём и не помогут.
Пара фрагментов скомпилированного кода. Почему бы ему не работать в release?
Оптимизация в release
Assembler
1
2
3
4
5
6
7
8
9
10
11
    int *ar;
    ar = a();
    
    cout << ar[0] << ar[1] << ar[2];
000219A5  push        3  
000219A7  push        ecx  
000219A8  push        2  
000219AA  push        ecx  
000219AB  push        1  
000219AD  mov         ecx,45AE0h  
000219B2  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (021A30h)
Без оптимизации в debug
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    int *ar;
    ar = a();
00C74457  call        a (0C710C8h)  
00C7445C  mov         dword ptr [ar],eax  
    
    cout << ar[0] << ar[1] << ar[2];
00C7445F  mov         eax,4  
00C74464  shl         eax,1  
00C74466  mov         esi,esp  
00C74468  mov         ecx,dword ptr [ar]  
00C7446B  mov         edx,dword ptr [ecx+eax]  
00C7446E  push        edx  
00C7446F  mov         eax,4  
00C74474  shl         eax,0  
00C74477  mov         edi,esp  
00C74479  mov         ecx,dword ptr [ar]  
00C7447C  mov         edx,dword ptr [ecx+eax]  
00C7447F  push        edx  
00C74480  mov         eax,4  
00C74485  imul        eax,eax,0  
00C74488  mov         ebx,esp  
00C7448A  mov         ecx,dword ptr [ar]  
00C7448D  mov         edx,dword ptr [ecx+eax]  
00C74490  push        edx  
    
    cout << ar[0] << ar[1] << ar[2];
00C74491  mov         ecx,dword ptr ds:[0C802DCh]  
00C74497  call        dword ptr ds:[0C802E0h]
0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 02:35
Цитата Сообщение от Ygg Посмотреть сообщение
Пара фрагментов скомпилированного кода. Почему бы ему не работать в release?
Не хочу в этом онанизме даже ковыряться...
Есть неубиенное правило: все локальные переменные переменные, объявленные в функции, после завершения функции перестают существовать. Всё. Точка.
Локальные переменные выделяются в кадре стека функции. После завершения функции кадр стека ликвидируется.
Нельзя возвращать из функции указатели на локальные переменные. А вот сами локальные структурные переменные, сколь угодно большого размера - возвращайте пожалуйста.
Code
1
2
3
4
5
6
7
8
9
10
11
struct ret {
   double val;
   int errcode;
}
...
ret func( ... ) {
   ret i;
   ret.val = 1.2345;
   ret.errcode = ENOMEM;
   return ret;
}
Вот здесь всё будет нормально.
0
475 / 427 / 290
Регистрация: 10.03.2015
Сообщений: 1,782
25.03.2018, 02:41
Цитата Сообщение от Olej Посмотреть сообщение
А что "работает" - так то показалось.
Я прекрасно понимаю, причем изначально указал на время жизни.

Однако, если использовать выделенную память под локальные данные сразу после момента присвоения, они не затираются мусором. Буквально на "единождый" вызов.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int* a()
{
    int b[3] = { 1,2,3 };
    return b;
}
 
int *b()
{
    int b[3] = { 1,2,3 };
    return *&b;
}
 
int *c()
{
    int *b = new int[3]{ 1,2,3 };
    return b;
}
 
int *d()
{
    int *b = new int[3]{ 1,2,3 };
    return *&b;
}
int main()
{
    setlocale(LC_ALL, "Russian");
 
    int *ar1, *ar2, *ar3, *ar4;
    ar1 = a();
    cout << ar1[0] << ar1[1] << ar1[2] << endl;
    ar2 = b();
    cout << ar2[0] << ar2[1] << ar2[2] << endl;
    cout << ar2[0] << ar2[1] << ar2[2] << endl;
    ar3 = c();
    ar4 = d();
    cout << ar3[0] << ar3[1] << ar3[2] << endl;
    cout << ar4[0] << ar4[1] << ar4[2] << endl;
 
    _getch();
    return 0;
}
А вот с памятью уже другой вопрос.
1/2/static мы уже не освободим.
3/4 пожалуйста.

Мог бы для нас глупых разъяснить все
Я подобные конструкции не использовал (даже не думал, что так делают), но теперь уже самому интересно, что будет твориться с памятью

Цитата Сообщение от nd2 Посмотреть сообщение
Разве?
Да
Изображения
 
0
 Аватар для Olej
322 / 170 / 24
Регистрация: 25.03.2012
Сообщений: 712
25.03.2018, 02:45
Цитата Сообщение от SuperKir Посмотреть сообщение
Однако, если использовать выделенную память под локальные данные сразу после момента присвоения, они не затираются мусором.
Это херня, вьюношо.

Добавлено через 54 секунды
Цитата Сообщение от SuperKir Посмотреть сообщение
Я подобные конструкции не использовал (даже не думал, что так делают),
За такое нужно увольнять с работы ... чтобы "не использовал"
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.03.2018, 02:45
Помогаю со студенческими работами здесь

Как работают указатели с массивами
Хочу на простом примере перестановки двух элементов уяснить - как работают указатели с массивами, но ничего не получается. Объясните на...

Как работают ссылки и указатели?
Не нашел описание того, почему именно так работает, везде говорится только то, что так надо делать и все Аргумент функции является...

В функцию с переменным числом параметроы передать указатели на функцию
Добрый вечер. По заданию нужно в функцию с переменным числом параметров передать имя функций, которые нужно вызвать. Долго думала,как имея...

Кнопки регулировки громкости на клавиатуре иногда не работают и/или работают некорректно
Здравствуйте, у меня возникает некая неполадка/баг со звуком. Пользуюсь я данной клавиатурой, как видно на ней есть 3 кнопки для...

Некорректно работают скрипы
Доброго времени суток! Недавно столкнулся с такой проблемой...В общем, не работают кнопки на сайтах, не открываются картинки в яндексе,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию группы. . .
Как я обхитрил таблицу Word
Alexander-7 21.03.2026
Когда мигает курсор у внешнего края таблицы, и нам надо перейти на новую строку, а при нажатии Enter создается новый ряд таблицы с ячейками, то мы вместо нервных нажатий Энтеров мы пишем любые буквы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru