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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 17, средняя оценка - 4.82
Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 20:44     Стек или динамическая память!? #1
Добрый вечер всем! Прошу ответить на вопрос (ниже приведен код): почему строка "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;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.01.2012, 20:44     Стек или динамическая память!?
Посмотрите здесь:

C++ Динамическая память и стек,различие
C++ Стек и динамическая память
C++ Динамическая память
Статическая память,Динамическая память. C++
C++ Динамическая память
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.01.2012, 21:17     Стек или динамическая память!? #2
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;
}
У Вас создаётся строковая константа Test, которая записывается в call-stack (вроде так он называется). Причём работа стека в Си++ примерно такая - переменные не "стираются", а "помечаются как свободные"... Здесь нужно понимать принцип работы стека.

В общем, Ваша строковая константа просто не была переписана другими переменными. Так как Функция вернула указатель, обращаясь по нему Вы обращаетесь к тому участку памяти где "была" и "возможно есть" эта самая строковая константа.

Такой недохак крайне нежелательно использовать. Лучше использовать кучу и самостоятельно высвобождать память.
Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 21:48  [ТС]     Стек или динамическая память!? #3
Бред... Работает даже с сылками... Все же хотелось бы узнать, почему так!?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
using namespace std;
 
int &Test()
{
    int a = 20;
    return a;
}
 
int main()
{
        int &p = Test();
        cout << p << endl;
}
p.s. В книге "C++ за 21 день" (автор Либерти, глава "День 9. Ссылки") есть подзаглавие "Не возвращайте ссылку на объект вне области видимости!" и приведен похожий пример (см. выше), только с объектами класса. Так вот: в конце есть "Предупреждение", в котором написано, что компилятор Borland хрен пропустит эту лазейку, а Microsoft наоборот... И никаких "НЕПРЕДСКАЗУЕМЫХ!!!!!" последствий я тут не наблюдаю =\\
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 21:53     Стек или динамическая память!? #4
Pavel.fromBy, ответ примерно таков.

в теле функции создается временный объект - строковая константа. затем создается еще один объект тоже строковая константа - для возврата. содержимое первой копируется полностью во вторую. затем все верно - первая умирает в теле функции а вторая возвращается.
Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 21:56  [ТС]     Стек или динамическая память!? #5
AzaKendler, если мне не изменяет память, то и та, которая вернется, тоже умрет (указатель по крайней мере точно, а на счет строки... эх). Не буду писать код... Так, на пальцах: есть класс Test, есть перегр. оператор+.
C++
1
2
3
4
Test a1;
Test a2;
Test a3;
a3 = a2+a1; //сработает оператор присваивания, а потом то, что вернуло a2+a1, умрет
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 21:59     Стек или динамическая память!? #6
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
И никаких "НЕПРЕДСКАЗУЕМЫХ!!!!!" последствий я тут не наблюдаю =\\
ну они могут быть. поскольку используется "примитивное" копирование по умолчанию, то для неких сложных объектов данные могут быть утеряны

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
которая вернется, тоже умрет
будет присвоен твоему char* думаю. поэтому как бы останется жив. а вот та что в теле точно умрет

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Все же хотелось бы узнать, почему так!?
а почему не должно работать? на твой взгляд в этом примере
Paporotnik
383 / 227 / 7
Регистрация: 06.07.2011
Сообщений: 512
28.01.2012, 22:00     Стек или динамическая память!? #7
"Память под строковые литералы выделяется статически, поэтому их возврат из функций безопасен" Б. Страуструп
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 22:03     Стек или динамическая память!? #8
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
a3 = a2+a1; //сработает оператор присваивания, а потом то, что вернуло a2+a1, умрет
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Test
{
public:
{
 
Test& operator+(Test& a)
{
// тут чето делается
return *this;
};
 
Test& operator = (Test& a)
{
// что то делаем
return *this;
}
 
}
 
 
}
 
поясни при сложении и присваивании что умрет?
AnyOne697
 Аватар для AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 532
28.01.2012, 22:03     Стек или динамическая память!? #9
Ну раз возврат безопасен, значит всё окей...

Ссылки?.. Нет, не слышал.

Непредсказуемых последствий вы не наблюдаете потому что сейчас программа содержит 15 строчек. Как только она вырастет до 100500 строчек в одном запуске из ста будет наблюдатся "непредвиденный случай". Наглядный пример - Microsoft Windows Vista.
Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 22:15  [ТС]     Стек или динамическая память!? #10
Paporotnik, та же фигня проскакивает и с int'ами (я про код в первом посте).

Не по теме:

AzaKendler, АААА.... Я запутался... Мое любопытство меня погубит!!!! Сейчас вспомню и напишу. Каша в голове, но operator+ должен возвращать значение, а не ссылку (сейчас буду вспоминать, почему)

AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 22:22     Стек или динамическая память!? #11
Pavel.fromBy, он должен обеспечивать отсутствие лишнего копирования, если это я явно не требуется.

Не по теме:

Я встрял. Все имитирую оргазм и ухожу с темы

Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 22:40  [ТС]     Стек или динамическая память!? #12
Все! Эврика ! На примере того же оператора+.... Выше кем-то было хорошая вещь написана (разъясню в коде):
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
#include <iostream>
 
using namespace std;
 
class Test         //мне это слово сегодня снится будет:D
{
private:
    int a;
 
public:
    Test (int _a): a(_a) { }
 
    Test operator+ (const Test &);
};
 
Test Test::operator+ (const Test &rhs)
{ return Test(a + rhs.a); }  // Пусть то, что я создаю в return назыв. объект 1. То, что возвращается - объект 2.
                             // И так, объект 1 копипастится в объект 2 и погибает (бедняга...:) ). Далее см. main()
 
int main()
{
    Test a1(20);
    Test a2(30);
    Test a3(40);
 
    a3 = a1+a2;  // Все вышесказанное и продолжим:) Это все <=> (a3 = объект 2). После присвоения объект 2 погибает. Все концы отрезаны
}
 
//С ссылками с operator+ бедааааа, ведь если возвращать по ссылке, то мне необходимо создать временный указатель, 
//выделить под него память и return'уть его, но как эту память потом освободить (ведь она должна освободиться)?! Утечка....
//(опять мой вопрос...-> Если не юзать кучу => ссылка, которую мы вернем, будет псевдонимом хрен знает чего, ведь объект удалится)
p.s. Памятник тому, кто разберется и объяснит

Не по теме:

Хотел посмотреть матч Шараповой и Азаренко в записи, так хрена...

AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 22:50     Стек или динамическая память!? #13
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Test Test::operator+ (const Test &rhs)
{ return Test(a + rhs.a); }
C++
1
2
3
4
5
6
Test& operator+(const Test& rhs)
{
 
a += rhs.a;
return *this;
}
по твоей просьбе в личном сообшении.

Ты создаешь временные копии объектов. Этого делать не надо, если этого явно не требуется.
В твоем примере временные объекты будут создаваться и уничтожаться отнимая время.
Просто так "от захотелось" следует избегать такого явления используя ссылки или указатели.
Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 22:52  [ТС]     Стек или динамическая память!? #14
AzaKendler, стояяяяятЬ! Вы путаете с operator+=
C++
1
2
3
4
5
6
....
int a = 20;
int b = 30;
...
a+b;  //не изменяет a
a+=b;//изменяет a
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 23:05     Стек или динамическая память!? #15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Test
{
public:
int a;
 operator int()
{
return a;
}
};
 
int main()
{
 
Test a;
Test b;
a.a = 55;
b.a = 66;
 
int z = a+b;
 
return 0;
}
Добавлено через 3 минуты
ЗЫ:
Я искренне надеюсь что сий пример помог чем либо.
Pavel.fromBy
 Аватар для Pavel.fromBy
13 / 13 / 1
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:07  [ТС]     Стек или динамическая память!? #16
AzaKendler, сори, если туплю, но чем это относится к вот этому - (опять мой вопрос...-> Если не юзать кучу => ссылка, которую мы вернем, будет псевдонимом хрен знает чего, ведь объект удалится) ??
AzaKendler
 Аватар для AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 23:12     Стек или динамическая память!? #17
Pavel.fromBy, это относится к вопросам про создание временных объектов твоего класса которого можно избежать.но ты почему то на нем настаиваешь. Ведь твои классы могут быть просто огромными. ну а уж копирование int думаю пережить можно.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16834 / 5255 / 323
Регистрация: 30.03.2009
Сообщений: 14,152
Записей в блоге: 26
28.01.2012, 23:14     Стек или динамическая память!? #18
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Добрый вечер всем! Прошу ответить на вопрос (ниже приведен код): почему строка "Test!" выводится на экран? Она же не была создана в дин. памяти, т.е. должна была "загнуться" после 1ой строки main(). Заранее благодарен...
См. сюда: Изменить значение указателя
Другими словами, компилятор создаёт объект с временем жизни "вся программа" и возвращает на него адрес. При этом более честно было бы у функции Test поменять тип с "char*" на "const char*"
Pavel.fromBy
 Аватар для 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;
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2012, 23:18     Стек или динамическая память!?
Еще ссылки по теме:

C++ Динамическая память с++
C++ Память. Стек или куча - есть ли преимущества одного кода над другим?
Динамическая структура данных (Стек) C++

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16834 / 5255 / 323
Регистрация: 30.03.2009
Сообщений: 14,152
Записей в блоге: 26
28.01.2012, 23:18     Стек или динамическая память!? #20
Другими словами, конструкция типа return "abc" является абсолютно законной и никаких кривых указателей не рожает

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Я не понимаю, почему строка жива (она же в стеке, который чистится после завершения работы функции.. Т.e. указатель будет, но он ДОЛЖЕН указывать на хрен пойми что)
Нет, указатель указывает на тот static объект (см. пост #18)
Yandex
Объявления
28.01.2012, 23:18     Стек или динамическая память!?
Ответ Создать тему
Опции темы

Текущее время: 13:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru