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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.82
Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
#1

Стек или динамическая память!? - C++

28.01.2012, 20:44. Просмотров 2217. Ответов 29
Метки нет (Все метки)

Добрый вечер всем! Прошу ответить на вопрос (ниже приведен код): почему строка "Test!" выводится на экран? Она же не была создана в дин. памяти, т.е. должна была "загнуться" после 1ой строки main(). Заранее благодарен...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
using namespace std;
 
char *Test()
{
    return "Test!";
}
 
int main()
{
    char *p = Test();
    cout << p << endl;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.01.2012, 20:44
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Стек или динамическая память!? (C++):

Стек и динамическая память - C++
Читаю книжку по с++. Для хранения переменных может использоваться стек или динамическая память. чтоб поместить в стек нужно объявить...

Динамическая память и стек,различие - C++
подскажите в чем различие дин.памяти по отношению к стеку..и почему дин память лучше..?

Память. Стек или куча - есть ли преимущества одного кода над другим? - C++
Здравствуйте, хотел спросить в чем различия. В чем тут недостатки и преимущества разных способов? Apple apple(); и Apple *apple = new...

Статическая память,Динамическая память. - C++
a) Статическая память. Двумерный массив. Дан массив целых чисел. В массиве есть отрицательные числа. Определить координаты левого нижнего...

Динамическая структура данных (Стек) - C++
Подскажите в чем ошибка, пожалуйста. Программа выдает ошибку (&quot;Прекращена работа программы..&quot;), когда выбираю &quot;y&quot; (добавление элементов...

Динамическая память [new] - C++
Если записать так: char *p; p = new char; cin&gt;&gt;p; for(int i=0; i&lt;strlen(p); i++) cout&lt;&lt;p&lt;&lt;endl;

29
Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:07  [ТС] #16
AzaKendler, сори, если туплю, но чем это относится к вот этому - (опять мой вопрос...-> Если не юзать кучу => ссылка, которую мы вернем, будет псевдонимом хрен знает чего, ведь объект удалится) ??
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 23:12 #17
Pavel.fromBy, это относится к вопросам про создание временных объектов твоего класса которого можно избежать.но ты почему то на нем настаиваешь. Ведь твои классы могут быть просто огромными. ну а уж копирование int думаю пережить можно.
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.01.2012, 23:14 #18
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Добрый вечер всем! Прошу ответить на вопрос (ниже приведен код): почему строка "Test!" выводится на экран? Она же не была создана в дин. памяти, т.е. должна была "загнуться" после 1ой строки main(). Заранее благодарен...
См. сюда: Изменить значение указателя
Другими словами, компилятор создаёт объект с временем жизни "вся программа" и возвращает на него адрес. При этом более честно было бы у функции Test поменять тип с "char*" на "const char*"
1
Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:17  [ТС] #19
AzaKendler, я же создавал примитивные примеры, чтобы узнать, про вопрос в первом посте Вот, откуда ноги растут (опять же, про свой вопрос):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.....
enum color    {red, yellow, green, blue, white};
....
//---------------------------------------------------------
                                         //return Color(string)
char *Body::retColor() const
{
    switch(itsColor)
    {
        case 0: return "red";
        case 1: return "yellow";
        case 2: return "green";
        case 3: return "blue";
        case 4: return "white";
    }
}
 
//---------------------------------------------------------
Я не понимаю, почему строка жива (она же в стеке, который чистится после завершения работы функции.. Т.e. указатель будет, но он ДОЛЖЕН указывать на хрен пойми что), когда я делаю так:
C++
1
cout << retColor() << endl;
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.01.2012, 23:18 #20
Другими словами, конструкция типа return "abc" является абсолютно законной и никаких кривых указателей не рожает

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Я не понимаю, почему строка жива (она же в стеке, который чистится после завершения работы функции.. Т.e. указатель будет, но он ДОЛЖЕН указывать на хрен пойми что)
Нет, указатель указывает на тот static объект (см. пост #18)
1
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 23:20 #21
Evg, Евгений очень хорошо что ты здесь.

очень хотелось бы четкого понимания

char *Test()
{
return "Test!";
}
Для всех думаю. Значит для "abc" возврат законный? Просто идет присваивание адреса "той" памяти другой переменной?
Хочу уточнить. Можно ли использовать данный указатель как критерий для сравнения, пока идет программа?
На форуме товарищи сказали что нет

C++
1
2
3
4
5
6
const char* p;
 
//.....
//.......
 
if(p == "Test")
0
Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:21  [ТС] #22
Evg, про строки, с трудом, но разобрался (хотя, не понятно почему он делает массив символов статическим). Спасибо. А как быть с этим:
C++
1
2
3
4
5
6
7
.....
int &func()
{
int a = 20;
return a;
}
....
Если в мейне принять результат этой функции ссылкой, то все, опять же, будет в порядке. Здесь та же ситуация?
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.01.2012, 23:23 #23
М... а из того описания непонятно? В общем

C
1
2
3
4
char *Test()
{
  return "Test!";
}
эквивалентно

C
1
2
3
4
5
static char tmp[6] = { 'T', 'e', 's', 't', '!', '\0' };
char* Test (void)
{
  return &(tmp[0]);
}
Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Evg, про строки, с трудом, но разобрался. Спасибо. А как быть с этим:
C++
1
2
3
4
5
6
7
.....
int &func()
{
int a = 20;
return a;
}
....
Если в мейне принять результат этой функции ссылкой, то все, опять же, будет в порядке. Здесь та же ситуация?
Нет, здесь как раз-таки опасная ситуация. Возвращается ссылка на локальный (а не глобальный) объект. Строка (а точнее, строковой литерал) по определению является глобальным объектом
2
Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:27  [ТС] #24
Evg, все, со строками покончено Не заметил, что статик до функции. Теперь с интами... Ситуация, может и опасная, но почему работает? Ведь не должно же!!! Объект умирает и ссылка является псевдонимом хрен знает чего... (где-то я уже это писал ).
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 23:29 #25
Evg,

C++
1
2
3
4
5
6
7
8
9
const char* p = "Test";
 
//.....
//.......
 
if(p == "Test")
{
 
}
можно так или нет? хочется узнать именно твое мнение. область памяти, адрес будут одинаковы?
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.01.2012, 23:31 #26
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Объект умирает
Объект умирает, но память, где этот объект лежал, загадить ещё никто не успел. Но если после вызова твоей func, возвращающей ссылку, ты вызовешь ещё какую-нибудь функцию, то она уже эту память подпортит

Вот тут я кидал ссылку Deep C
Там в том числе и про этот случай рассказывается. Кстати, func может возвращать хоть ссылку, хоть указатель - по сути дела это одно и то же
1
NoMasters
Псевдослучайный
1765 / 1107 / 74
Регистрация: 13.09.2011
Сообщений: 3,149
28.01.2012, 23:33 #27
Pavel.fromBy, после выхода из функции память в стеке не очищается, а просто оказывается выше текущей вершины. Так что, если ничего не успело занять там место и страницу памяти не вернули системе, данные там останутся те же. Но рассчитывать на это не стоит, если случится последнее "если" приложение рухнет с сегфолтом.
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.01.2012, 23:33 #28
Цитата Сообщение от AzaKendler Посмотреть сообщение
можно так или нет? хочется узнать именно твое мнение. область памяти, адрес будут одинаковы?
В данной программе имеется два строковых литерала. Поскольку они по стандарту являются const-объектами, то компилятор имеет право эти два объекта положить в одно и то же место памяти. На вопрос "можно или нет" ответ "нельзя". На вопрос "будут ли одинаковыми" ответ "зависит от компилятора"
1
Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:34  [ТС] #29
Evg, премного благодарен! Вопросов нет... За ссылку отдельное спасибо... Хоть и с английским не очень дружу, обязательно посмотрю!
NoMasters, и вам спасибо!
0
Evg
Эксперт CАвтор FAQ
18383 / 6431 / 441
Регистрация: 30.03.2009
Сообщений: 17,852
Записей в блоге: 28
28.01.2012, 23:36 #30
Цитата Сообщение от Evg Посмотреть сообщение
На вопрос "можно или нет" ответ "нельзя"
Тут из разряда "нельзя, но если очень хочется, то можно". Если программа пишется под конкретную версию компилятора, если программист заведомо знает, что компилятор умеет одинаковые строки класть в одну память, если программист знает, что в качестве аргумента сравнения всегда будет указатель, инициализированный именно строковым литералом, то можно. Но при этом программист будет сидеть на бочке с динамитом
0
28.01.2012, 23:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2012, 23:36
Привет! Вот еще темы с ответами:

Динамическая память - C++
Есть 2 массива одной размерности: int *m1 = new int , *m2 = new int ; где N, M некие числа. Собственно вопрос: как...

Динамическая память C++ - C++
Народ, подскажите, плиз, что я делаю не так? Надо посимвольно ститать строку, в процессе выделяя ей ровно столько памяти, сколько...

Динамическая память - C++
Помогите перевести массивы в динамическую память пожалуйста + почему-то не работает запись в файл(не перезаписывает). #include &lt;iostream&gt;...

Динамическая память - C++
Здраствуйте!!!! Помогите выделить память под двумерные массив элементами которого являются слова. Было бы хорошо листинг программы....


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

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

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