Форум программистов, компьютерный форум CyberForum.ru

Есть ли утечка памяти в этом случае? - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Определить число нулей и единиц в массиве http://www.cyberforum.ru/cpp-beginners/thread887546.html
диапазон изменения значений элементов массива 0 или 1 Сделать два варианта программы: -элементы массива задаются пользователем -заполняются с помощью генератора случайных чисел
C++ Определить число нулей и единиц в массиве диапазон изменения значений элементов массива 0 или 1 Сделать два варианта программы: -элементы массива задаются пользователем -заполняются с помощью генератора случайных чисел http://www.cyberforum.ru/cpp-beginners/thread887541.html
C++ Какую роль выполняют идентификаторы в приведенном коде?
Подскажите пожалуйста,какие в данной задаче идентификаторы и их назначение в ней. #include <iostream> #include <algorithm> #include <vector> #include <iterator> #include <cassert> using namespace std; int main()
Ошибка в функции (function: должна возвращать значение) C++
ребят, компилятор выдает error C4716: function: должна возвращать значение что это значит? как с этим бороться? #include "stdafx.h" #include <math.h> #include <string.h> #include <conio.h> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <time.h>
C++ Найти количество квадратов нечётных чисел среди компонентов файла http://www.cyberforum.ru/cpp-beginners/thread887521.html
Заполнить файл 7 натуральными числами, полученными с помощью генератора случайных чисел. Найти количество квадратов нечётных чисел среди компонентов файла.
C++ Упорядочить список студентов по оценке, полученной на экзамене и распечатать его На диске имеется файл данных STUDENT.DAT. Упорядочить список студентов по оценке, полученной на экзамене по мат. анализу и распечатать его. подробнее

Показать сообщение отдельно
IGPIGP
Комп_Оратор)
 Аватар для IGPIGP
6228 / 2957 / 287
Регистрация: 04.12.2011
Сообщений: 7,886
Записей в блоге: 3
02.06.2013, 14:43     Есть ли утечка памяти в этом случае?
А я согласен с alex_x_x в том, что ссылка на локально созданный, динамический объект не обязательно не валидна.
Ссылка - псевдоним переменной. Иногда говорят, что это указатель который всегда разыменовывается.
Классический пример возврата ссылки на локальную переменную:
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;
//вот возврат ссылки на локальную стековую переменную
int& retInt(){int c=5;  return c;}
int main()
{
int& a=retInt();//
for(int i=0; i<1000; ++i)cout<<a<<endl;//чушь как и должно быть (стек освободился от переменной с, - её нет)
system("pause");
cout << endl;
return 0;
}
С псевдонимом вроде ясно, но что значит, что ссылка это указатель, который всегда разыменовывается? Это же иносказание. Я попробовал представить так:
Указатель при разыменовании не просто представляет значение переменной на которую указывает, он предоставляет имя переменной через которую предоставляется значение. Когда одной переменной присваивается разыменованный указатель, то промежуточный этап не важен и можно считать, что в переменную копируется значение по указателю. Другое дело когда разыменованный указатель присваивается ссылке. Пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
using namespace std;
int main()
{
int a=123;//
int& b = a;//b - псевдоним a, адреса a и b совпадают
int* p=&a;
int& c = *p;//с - псевдоним a, адреса a и с совпадают, 
//но p лишь предоставил переменную a переменной c и от того жив ли он уже ничего не зависит!
p=0;//не важно какое у него значение, главное, чтобы не было явного освобождения (delete) по "старому" адресу (a)
cout<<a<<endl;//123
cout<<&a<<endl;
cout<<b<<endl;//123
cout<<&b<<endl;
cout<<c<<endl;//123
cout<<&c<<endl;
system("pause");
cout << endl;
return 0;
}
Пример с возвратом ссылки на динамический объект. Такой объект не имеет имени, но безымянная переменная создаётся. Указатель на неё,- на стеке и будет уничтожен, но она сама - (анонимная переменная), хоть и создаётся локально, но связана с динамическим объектом и обладает его временем жизни (? это на правах вопроса). Вернее может сказать, что всё что в ней описывает участок динамической памяти, остаётся жить, а имени нет и разрушать по сути нечего.
Во всяком случае похоже принимающая ссылка валидна:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    
#include <iostream>
using namespace std;
int& MakeInt ();
int main()
{
int& a =  MakeInt ();
for(int i=0; i<1000; ++i)cout<<a<<endl;//всё живо (может цикл маловат?))
system("pause");
cout << endl;
return 0;
}
int& MakeInt ()
{    
    int* NewInt = new int (123);
    
    return *NewInt;
}
И напоследок этот же пример с попыткой показать, что разрушение локального указателя не освобождает память и ссылка им предоставляемая (безымянное имя)) живет после выхода из зоны видимости:
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
#include <iostream>
using namespace std;
int& MakeInt (int* ptrSpy);//передаём шпиёна
int main()
{
int* p=0;
int& a =  MakeInt (p);
cout<<"out just after NewInt() p= "<<p<<endl;//уже не указывает (NewInt уничтожен)
cout<<a<<endl;
cout<<&a<<endl;//а тут информация о адресе в дин. памяти есть (она никак не связана с жизнью указателя NewInt)
p=&a;//устанавливаем "на место"
delete p;//похоже a связана с памятью выделенной new при инициализации NewInt, посредством анонимной переменной которая на неё ссылается и не уничтожена
//так как память на которую она ссылается (динамическая же) не освобождена, при этом она получена разыменованием NewInt, но её время
//жизни определяется связанной с нею памятью, а не временем жизни указателя. То есть следующий оператор - обращение в никуда:
cout<<a<<endl;//так и есть. То есть, явное освобождение памяти и разрушение локальной переменной-указателя не одно и то же.
system("pause");
cout << endl;
return 0;
}
int& MakeInt (int* p)
{    
 int* NewInt = new int (123);
cout<<"in NewInt() NewInt= "<<NewInt<<endl;
 p=NewInt; 
 cout<<"in NewInt() p= "<<p<<endl;//указывает с NewInt на один адрес
    return *NewInt;
}
Вполне вероятно, что локальная созданная ссылка на динамический объект может реализовываться по-разному, во всяком случае, VS C++ демонстрирует её живучесть по сравнению с локальным указателем. Более того, предупреждения о возврате локальной ссылки не выдаёт, как это имеет место быть в первом примере, (то есть локально созданная и локально "обитающая", не одно и тоже?), как в самом первом случае, где всё предельно ясно: локальная переменная - ссылка - кирдык.
 
Текущее время: 00:54. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru