Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/48: Рейтинг темы: голосов - 48, средняя оценка - 4.56
 Аватар для Intel~lect
137 / 126 / 14
Регистрация: 03.07.2012
Сообщений: 355

Почему локальная переменная не уничтожается после выхода из функции

13.07.2012, 15:26. Показов 9843. Ответов 21
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В функции создается строка char *pn = new char[ strlen(temp) + 1 ];. Мне непонятно почему при выходе из функции эта строка доступна в main()? Почему эта строка не удаляется после выхода из функции?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char *getName(void)
{
    char temp[80];
    
    cout << "Enter last name: ";
    cin >> temp;
 
    char *pn = new char[ strlen(temp) + 1 ];
    strcpy(pn, temp);
 
    return pn;
}
 
int main()
{
   char *name;
 
   name = getName();
}
Объясните, пожалуйста, что вообще там происходит.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.07.2012, 15:26
Ответы с готовыми решениями:

Почему переменная "d" не была удалена из стека после выхода из функции?
Почему переменная &quot;d&quot; не была удалена из стека после выхода из функции? #include&quot;stdafx.h&quot; #include&quot;iostream&quot; using...

Уничтожается переменная по выходу из функции. так не должно быть
Все доброго времени суток! В процессе отладки программки возник один вопрос... Есть функция: void bignum_fromhex(bignum_digit_t* num,...

Локальная переменная внутри статической функции
Всем доброго дня! Из данного примера выяснилось, что при обьявлении функции func_1() статической, переменная x внутри этой ...

21
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38161 / 21096 / 4306
Регистрация: 12.02.2012
Сообщений: 34,683
Записей в блоге: 14
13.07.2012, 15:28
Потому, что переменные, создаваемые оператором new - не локальные.
1
 Аватар для Intel~lect
137 / 126 / 14
Регистрация: 03.07.2012
Сообщений: 355
13.07.2012, 15:41  [ТС]
Цитата Сообщение от Catstail Посмотреть сообщение
Потому, что переменные, создаваемые оператором new - не локальные.
Как же не локальные если она внутри другой функции.? Переменная temp[80] уничтожается после выхода а pn что остается?
В pn копируется строка temp и она не удаляется?
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38161 / 21096 / 4306
Регистрация: 12.02.2012
Сообщений: 34,683
Записей в блоге: 14
13.07.2012, 15:54
Локальные переменные создаются в стеке и освобождаются после выхода из функции. Переменные, создаваемые оператором new, "живут" не в стеке, а в куче. Куча глобальна. Поэтому указатель на массив из кучи можно вернуть из функции (оператором return) и использовать в другой функции.

Добавлено через 3 минуты
Цитата Сообщение от Intel~lect Посмотреть сообщение
Переменная temp[80] уничтожается после выхода а pn что остается?
- обе уничтожаются... Но не уничтожается блок памяти в куче, на который указывала pn. Этот указатель возвращается оператором return.
1
 Аватар для Schizorb
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
13.07.2012, 15:55
Память под строку выделяется в куче, совместно используемой всеми функциями. Такая память не освобождается по завершению функции, для этого надо вызывать delete.

А сам по себе указатель pn - локальная переменная, содержащий адрес первого элемента этой строки. return pn - просто возвращает значение этого адреса. Как в случае

C++
1
2
3
4
5
int foo()
{
    int x = 8;
    return x;
}
Тоже возвращается значение локальной переменной, только типа int.
1
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
13.07.2012, 16:07
Цитата Сообщение от Intel~lect Посмотреть сообщение
В pn копируется строка temp и она не удаляется?
Не в pn, а в область памяти размером strlen(temp) + 1, которая выделяется в динамической памяти, и адрес которой помещается в указатель pn. Этот адрес, после выхода из функции getName() нужно сохранить (так как pn - локальная переменная). Что и делается в строке: name = getName(); Теперь указатель name хранит адрес области памяти, куда скопировали temp.
1
 Аватар для Intel~lect
137 / 126 / 14
Регистрация: 03.07.2012
Сообщений: 355
13.07.2012, 16:43  [ТС]
Спасибо всем что объяснили Вроде немного стало понятно. А то вот читаю книгу и главное никак не могу разобраться с этой задачей.

Добавлено через 36 минут
Цитата Сообщение от alsav22 Посмотреть сообщение
в область памяти размером strlen(temp) + 1, которая выделяется в динамической памяти
Тогда что находится в этой динамической памяти доступно в любом месте программы? Просто нужно знать ее адрес?
0
Нуб со стажем
 Аватар для kent
36 / 34 / 10
Регистрация: 19.02.2012
Сообщений: 118
13.07.2012, 16:52
Цитата Сообщение от Intel~lect Посмотреть сообщение
Тогда что находится в этой динамической памяти доступно в любом месте программы? Просто нужно знать ее адрес?
Да. Если эта память не была возвращена в кучу
1
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
13.07.2012, 17:18
Цитата Сообщение от Catstail Посмотреть сообщение
Потому, что переменные, создаваемые оператором new - не локальные.
Catstail, что то вы путаете

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
#include <iostream> 
 
char getSymbol(void)
{
    char p;
 
    char *arr = new char [ 20 ];
    
   std::cout << "Enter a symbol :  ";
 
    std::cin >> p;
 
    return ( p );
}
 
int main()
{
 
   std::cout << getSymbol();
 
   std::cout << arr;   //   НЕОБЪЯВЛЕННЫЙ ИДЕНТИФИКАТОР
 
   return ( 0 );
}
Цитата Сообщение от Intel~lect Посмотреть сообщение
В функции создается строка char *pn = new char[ strlen(temp) + 1 ];. Мне непонятно почему при выходе из функции эта строка доступна в main()?
ПОСЛЕ выхода из функции она не доступна
1
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
13.07.2012, 17:30
Цитата Сообщение от kent Посмотреть сообщение
Да. Если эта память не была возвращена в кучу
Intel~lect, после того, как эта память перестанет быть нужной, необходимо её освободить :
C++
1
delete [] name;
, чтобы не было утечки памяти.

Добавлено через 9 минут
Цитата Сообщение от MrCold Посмотреть сообщение
Catstail, что то вы путаете
Просто не так выразился. Наверное, имелось ввиду, что указатель, который возвращает new, содержит адрес памяти не в области, предназначенной для хранения локальных переменных.
0
 Аватар для Intel~lect
137 / 126 / 14
Регистрация: 03.07.2012
Сообщений: 355
13.07.2012, 17:30  [ТС]
Цитата Сообщение от MrCold Посмотреть сообщение
ПОСЛЕ выхода из функции она не доступна
Нет. Она все таки доступна Правда другим способом.
C++
1
2
3
4
5
6
int main()
{
   char *name;
 
   name = getName();  // в getName() создается строка а в main() ее видно
}
А вот еще вопрос есть. Если в getName() используется оператор new для выделения блока памяти а потом эту память нужно удалять. Но где? В main()?
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
13.07.2012, 17:40
Intel~lect,

после оперетора return функция завершает свою работу

C++
1
2
3
4
5
6
7
8
9
10
int main()
{
   char *name, *name2;
 
   name = getName();  // здесь работает 
.....................................  // здесь не работает 
 
name2 = getName();  // здесь СНОВА работает 
 
}
0
Супер-модератор
Эксперт функциональных языков программированияЭксперт Python
 Аватар для Catstail
38161 / 21096 / 4306
Регистрация: 12.02.2012
Сообщений: 34,683
Записей в блоге: 14
13.07.2012, 17:57
Я действительно не вполне удачно выразился. Указатель pn - локальная переменная. Длиной в 4 байта. Содержит адрес, указывающий в кучу. Этот адрес возвращается в вызывающую программу. Переменная pn (4 байта в стеке) уничтожается при выходе из функции.
1
 Аватар для Schizorb
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
13.07.2012, 18:20
Цитата Сообщение от MrCold Посмотреть сообщение
ПОСЛЕ выхода из функции она не доступна
Переменная с именем pn, естественно недоступна в main, потому что имеет локальную область видимости внутри функции getSymbol.

Но сама строка, динамически размещённая в куче, доступна из других функций.
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
13.07.2012, 18:27
Цитата Сообщение от Intel~lect Посмотреть сообщение
А вот еще вопрос есть. Если в getName() используется оператор new для выделения блока памяти а потом эту память нужно удалять. Но где? В main()?
Можно в main(), можно не в main(). В вашем коде в main().
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
13.07.2012, 18:28
Цитата Сообщение от Schizorb Посмотреть сообщение
Но сама строка, динамически размещённая в куче, доступна из других функций.
Schizorb, пожайлуста, кодом если не трудно
0
 Аватар для Schizorb
512 / 464 / 81
Регистрация: 07.04.2012
Сообщений: 869
Записей в блоге: 1
13.07.2012, 18:31
MrCold, самый первый пост в теме. В функции main создаётся указатель, ему присваивается адрес строки, память под которую выделена в другой функции.
0
 Аватар для Intel~lect
137 / 126 / 14
Регистрация: 03.07.2012
Сообщений: 355
13.07.2012, 18:33  [ТС]
Цитата Сообщение от alsav22 Посмотреть сообщение
Можно в main(), можно не в main(). В вашем коде в main().
Я это что спросил. Вот если строка динамически создается в одной функции, а удалять в другой. Ведь так и запутаться можно! Неудобно.
Да и забыть также можно про освобождение памяти.
0
873 / 771 / 173
Регистрация: 11.01.2012
Сообщений: 1,942
13.07.2012, 18:34
Schizorb, Ага, тогда понятно
0
5499 / 4894 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
13.07.2012, 18:40
Цитата Сообщение от Schizorb Посмотреть сообщение
Но сама строка, динамически размещённая в куче, доступна из других функций.
c помощью указателя, возвращённого оператором new,и ,предусмотрительно, сохранённого в указателе name.

Добавлено через 2 минуты
Цитата Сообщение от Intel~lect Посмотреть сообщение
Да и забыть также можно про освобождение памяти.
На совести программиста следить за этим, или использовать классы с автоматическим управлением памятью, которые сами за этим следят.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
13.07.2012, 18:40
Помогаю со студенческими работами здесь

Почему выводит ошибку C4700, что локальная переменная неинициализированна, если она инициализированна
Все это более чем странно. #include &lt;iostream&gt; #include &lt;locale.h&gt; #include &lt;time.h&gt; #include &lt;cstdlib&gt; using namespace std; ...

Локальная переменная масив не создаеться в вызваной функции
Здравствуйте, Не укладывется в голове, после завершения рекурсий (т.е.контроль передаеться на if(ii==1){return 0;}) наступает цикл for...

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

Переменная запоминающаяся после выхода из программы
Подскажите можно ли задать какую то переменную в java чтобы она сохранилась и после перезапуска программы. Не используя при этом внешних...

Почему в выводе выдаются предупреждения "warning C4101: sm: неиспользованная локальная переменная"
// gd.cpp: определяет точку входа для консольного приложения. // #include &quot;stdafx.h&quot; #include &quot;stdlib.h&quot; #include...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru