Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 409
#1

Почему плохо возвращать указатель из функции? - C++

03.07.2014, 13:06. Просмотров 533. Ответов 14
Метки нет (Все метки)

Почему плохо то, что мы возвращаем указатель?(return rez)
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
#include <stdio.h>
#include <stdlib.h>
#define SIZE    10
 
int* MinMax(int* d, int len){
    int i;
    int min,max;
    int rez[2];
 
    min=max=d[0];
    for(i=0;i<len;i++){
        if(d[i]>max)    max=d[i];
        if(d[i]<min)    min=d[i];
    }
    rez[0]=min;
    rez[1]=max;
    return rez;
}
 
 
void main(){
    int data[SIZE]={12,5,-6,25,3,0,7,34};
 
    printf("Min=%d  Max=%d  \n",MinMax(data,SIZE)[0],MinMax(data,SIZE)[1]);
    system("pause");
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.07.2014, 13:06
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Почему плохо возвращать указатель из функции? (C++):

Функция должна возвращать указатель на первый элемент массива,удовлетворяющий условию - C++
Функция должна возвращать указатель на первый элемент массива,удовлетворяющий условию(в данном случае используется указатель на бинарный...

Почему указатель на указатель объявляется как float **A; - C++
Почему float?

Почему не хочет возвращать main() ? - C++
Вот практикуюсь в C++, а тут return main(); не хочет работать - красным main() подчёркивает. Почему здесь ошибка, подскажите пожалуйста. ...

Почему перегруженный оператор = должен возвращать ссылку на объект - C++
Объясните доступно пожалуйста. Почему перегруженный оператор= должен возвращать ссылку на объект? А оператор+ может возвращать как...

почему нельзя в операторе + возвращать оригинальное значение(по ссылке), а не копию. - C++
Второй час сижу над одним и тем же кодом и не могу понять, что не так. Не могу сообразить почему нельзя в операторе + возвращать...

Реализация двоичных деревьев поиска: Зачем в параметрах функции используется указатель на указатель - C++
Всем привет, встретил в книге такой пример добавления узла в дерево: typedef struct tree { int data; tree *left, *right,...

14
nmcf
5538 / 4848 / 1644
Регистрация: 14.04.2014
Сообщений: 19,674
03.07.2014, 13:08 #2
Потому что это локальная переменная, существующая только внутри функции MinMax.
0
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 409
03.07.2014, 13:19  [ТС] #3
Потому что это локальная переменная, существующая только внутри функции MinMax.
а посему тогда
C
1
 printf("Min=%d  Max=%d  \n",MinMax(data,SIZE)[0],MinMax(data,SIZE)[1]);
нормально отрабатывает?
0
rikimaru2013
C++ Game Dev
2439 / 1133 / 240
Регистрация: 30.11.2013
Сообщений: 3,690
03.07.2014, 13:20 #4
Багоюзер))) Весёлый код - первый раз глянул не поверил, что компилируется ))

1) баг, что значение по адресу умершей локальной переменной не записывается
2) баг, что вызывая функцию с индексом вы обращаемся к значению return + index
0
CheshireCat
Эксперт С++
2895 / 1244 / 78
Регистрация: 27.05.2008
Сообщений: 3,397
03.07.2014, 13:25 #5
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Весёлый код - первый раз глянул не поверил, что компилируется ))
А он и не компилируется:
error: '::main' must return 'int'
GCC 4.8.1
0
nmcf
5538 / 4848 / 1644
Регистрация: 14.04.2014
Сообщений: 19,674
03.07.2014, 13:25 #6
Ну может они остаются в памяти, поэтому срабатывает, но гарантий нет. Массив опиши в main() и передавай его в MinMax, а функцию сделай void.
0
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 409
03.07.2014, 13:26  [ТС] #7
1) баг, что значение по адресу умершей локальной переменной не записывается
имеете ввиду на место указателя не записывается что то другое??

Наверно потому что короткий код, не успевает что то другое записаться, 2-ой баг по этой же причине наверно работает
0
Ilot
Модератор
Эксперт С++
1823 / 1181 / 232
Регистрация: 16.05.2013
Сообщений: 3,118
Записей в блоге: 5
Завершенные тесты: 1
03.07.2014, 13:28 #8
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
нормально отрабатывает?
Потому, что память была освобождена, но затерта.
0
rikimaru2013
C++ Game Dev
2439 / 1133 / 240
Регистрация: 30.11.2013
Сообщений: 3,690
03.07.2014, 13:28 #9
Компилируется VS2012
0
Zla9_Kolu4ka
2 / 2 / 0
Регистрация: 28.08.2013
Сообщений: 409
03.07.2014, 13:32  [ТС] #10
А тут почему норм, тоже локальная переменная возвращается
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
#include <stdio.h>
#include <stdlib.h>
#define SIZE    10
 
int Max(int d[],int len){
    int i;
    int m;
    //if()
    m=d[0];
    for(i=0;i<len;i++)
        if(d[i]>m)  m=d[i];
    return m;
}
 
 
void main(){
    int data[SIZE] = {2,3,8,1,-3,0,2};
    
 
    int max = data[0];
    int min = data[0];
 
    printf("max = %d \n", Max(data,SIZE));
 
    system("pause");
}
слышал, что значение копируется во временную переменную компилятора, а потом отрабатывает где то в другом месте, в данном случае в main(), printf("max = %d \n", Max(data,SIZE));
почему не сделают такой же фокус с указателями??
могли указатель в какую нить переменную компилятора скопировать и все!(Данные копировать не надо)

Потому, что память была освобождена, но затерта.
т.к правильно работает, то память как раз не была затерта
0
rikimaru2013
C++ Game Dev
2439 / 1133 / 240
Регистрация: 30.11.2013
Сообщений: 3,690
03.07.2014, 13:37 #11
Цитата Сообщение от Zla9_Kolu4ka Посмотреть сообщение
А тут почему норм, тоже локальная переменная возвращается
это разные вещи! На место Max(data,SIZE) подставляется числовой литерал и всё норм. А раньше твоя программа обращалась к адресу, хотя программа не знала, что там переменная и могла перезаписать ту ячейку памяти. Как-то так! Ну а ща баг с индексом спс ) Научила хитростям жизни)
0
nmcf
5538 / 4848 / 1644
Регистрация: 14.04.2014
Сообщений: 19,674
03.07.2014, 13:44 #12
Я же говорю, данные просто остались в стеке и не были затёрты, функция вернула указатель на то место и их видно, просто удачное стечение обстоятельств.
0
Tulosba
03.07.2014, 15:20
  #13

Не по теме:

Цитата Сообщение от nmcf Посмотреть сообщение
просто удачное стечение обстоятельств.
В данном случае такая "удача" как раз порождает мифы из разряда "Но раньше же всё работало".

0
AlexVRud
459 / 170 / 44
Регистрация: 04.07.2014
Сообщений: 475
04.07.2014, 17:38 #14
В первом случае ты возвращаешь указатель на локальную переменную (которая хранится в стеке). Тебе никто не гарантирует правильный порядок вычисления параметров, но получалось следующее: без оптимизации, вычислялись параметры printf и сохранялись сразу после вычислений в неявные локальные переменные. Но достаточно добавить оптимизацию и можно получить результат "Min=0 Max=0".

Во втором случае, возвращается не локальная переменная, а её значение. Т.е. происходит копирование из локальной переменной.

Если ты хочешь вернуть два числа, то используй структуры. Вернуть массив фиксированного размера в Си (и как следствие в С++) ты таким путём не сможешь.

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
#include <stdio.h>
#include <stdlib.h>
#define SIZE    10
 
typedef struct {
    int min;
    int max;
} SMinMax;
 
SMinMax min_max(int* d, int len){
    int i;
    SMinMax rez={d[0],d[0]};
 
    for(i=1;i<len;i++){
        if(d[i]<rez.min) rez.min=d[i];
        if(d[i]>rez.max) rez.max=d[i];
    }
    return rez;
}
 
int main(){
    int data[SIZE]={12,5,-6,25,3,0,7,34};
    printf("Min=%d  Max=%d\n", min_max(data,SIZE).min, min_max(data,SIZE).max);
    system("pause");
    return 0;
}
0
Jewbacabra
Эксперт PHP
2656 / 2243 / 844
Регистрация: 24.04.2014
Сообщений: 6,744
04.07.2014, 19:50 #15
Цитата Сообщение от AlexVRud Посмотреть сообщение
Вернуть массив фиксированного размера в Си (и как следствие в С++) ты таким путём не сможешь.
C++ 11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <array>
 
using namespace std;
 
array<int, 3> foo() {
    array<int, 3> arr = {1, 2, 3};
    cout << &arr[0] << endl;
    return arr;
}
 
int main() {
    array<int, 3> arr = foo();
    cout << &arr[0] << endl;
}
0
04.07.2014, 19:50
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.07.2014, 19:50
Привет! Вот еще темы с ответами:

Почему перегруженные шаблоны функций должны возвращать один и тот же тип? - C++
Так как я еще очень плохо знаю шаблоны и никак не могу понять. Почему у всех перегруженных шаблонных функций с одинаковыми именами так же...

Уточняющий вопрос: почему при перегрузке оператора [] необходимо возвращать ссылку? - C++
Сабж. Ну, то есть есть класс, что-то такое: #include &lt;iostream&gt; using namespace std; class arr { public: explicit...

Объяснить работу функции, возвращающей указатель на указатель на char - C++
Добрый день! Сможете объяснить что означает запись char **InputFile(int &amp;strings);? Почему именно двойное **? Буду очень благодарна...

Указатель на указатель, функции для создания новых массивов? - C++
Всем привет! У меня в коде есть несколько новых массивов, чтобы не повторяться я создам функцию которая будет выделять память под новые...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru