Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/21: Рейтинг темы: голосов - 21, средняя оценка - 4.57
 Аватар для Pavel.fromBy
13 / 13 / 0
Регистрация: 31.12.2011
Сообщений: 83

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

28.01.2012, 20:44. Показов 4340. Ответов 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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.01.2012, 20:44
Ответы с готовыми решениями:

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

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

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

29
 Аватар для AnyOne697
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
28.01.2012, 21:17
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 (вроде так он называется). Причём работа стека в Си++ примерно такая - переменные не "стираются", а "помечаются как свободные"... Здесь нужно понимать принцип работы стека.

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

Такой недохак крайне нежелательно использовать. Лучше использовать кучу и самостоятельно высвобождать память.
1
 Аватар для Pavel.fromBy
13 / 13 / 0
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 21:48  [ТС]
Бред... Работает даже с сылками... Все же хотелось бы узнать, почему так!?
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 наоборот... И никаких "НЕПРЕДСКАЗУЕМЫХ!!!!!" последствий я тут не наблюдаю =\\
1
 Аватар для AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
Записей в блоге: 15
28.01.2012, 21:53
Pavel.fromBy, ответ примерно таков.

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

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

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Все же хотелось бы узнать, почему так!?
а почему не должно работать? на твой взгляд в этом примере
0
385 / 229 / 12
Регистрация: 06.07.2011
Сообщений: 512
28.01.2012, 22:00
"Память под строковые литералы выделяется статически, поэтому их возврат из функций безопасен" Б. Страуструп
1
 Аватар для AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
Записей в блоге: 15
28.01.2012, 22:03
Цитата Сообщение от 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;
}
 
}
 
 
}
 
поясни при сложении и присваивании что умрет?
0
 Аватар для AnyOne697
134 / 106 / 10
Регистрация: 22.05.2010
Сообщений: 533
28.01.2012, 22:03
Ну раз возврат безопасен, значит всё окей...

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

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

Не по теме:

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

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

Не по теме:

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

0
 Аватар для Pavel.fromBy
13 / 13 / 0
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 22:40  [ТС]
Все! Эврика ! На примере того же оператора+.... Выше кем-то было хорошая вещь написана (разъясню в коде):
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. Памятник тому, кто разберется и объяснит

Не по теме:

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

0
 Аватар для AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
Записей в блоге: 15
28.01.2012, 22:50
Цитата Сообщение от 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;
}
по твоей просьбе в личном сообшении.

Ты создаешь временные копии объектов. Этого делать не надо, если этого явно не требуется.
В твоем примере временные объекты будут создаваться и уничтожаться отнимая время.
Просто так "от захотелось" следует избегать такого явления используя ссылки или указатели.
0
 Аватар для Pavel.fromBy
13 / 13 / 0
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 22:52  [ТС]
AzaKendler, стояяяяятЬ! Вы путаете с operator+=
C++
1
2
3
4
5
6
....
int a = 20;
int b = 30;
...
a+b;  //не изменяет a
a+=b;//изменяет a
0
 Аватар для AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
Записей в блоге: 15
28.01.2012, 23:05
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 минуты
ЗЫ:
Я искренне надеюсь что сий пример помог чем либо.
0
 Аватар для Pavel.fromBy
13 / 13 / 0
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:07  [ТС]
AzaKendler, сори, если туплю, но чем это относится к вот этому - (опять мой вопрос...-> Если не юзать кучу => ссылка, которую мы вернем, будет псевдонимом хрен знает чего, ведь объект удалится) ??
0
 Аватар для AzaKendler
214 / 116 / 14
Регистрация: 30.05.2011
Сообщений: 1,772
Записей в блоге: 15
28.01.2012, 23:12
Pavel.fromBy, это относится к вопросам про создание временных объектов твоего класса которого можно избежать.но ты почему то на нем настаиваешь. Ведь твои классы могут быть просто огромными. ну а уж копирование int думаю пережить можно.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
28.01.2012, 23:14
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Добрый вечер всем! Прошу ответить на вопрос (ниже приведен код): почему строка "Test!" выводится на экран? Она же не была создана в дин. памяти, т.е. должна была "загнуться" после 1ой строки main(). Заранее благодарен...
См. сюда: Изменить значение указателя
Другими словами, компилятор создаёт объект с временем жизни "вся программа" и возвращает на него адрес. При этом более честно было бы у функции Test поменять тип с "char*" на "const char*"
1
 Аватар для Pavel.fromBy
13 / 13 / 0
Регистрация: 31.12.2011
Сообщений: 83
28.01.2012, 23:17  [ТС]
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
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
28.01.2012, 23:18
Другими словами, конструкция типа return "abc" является абсолютно законной и никаких кривых указателей не рожает

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Я не понимаю, почему строка жива (она же в стеке, который чистится после завершения работы функции.. Т.e. указатель будет, но он ДОЛЖЕН указывать на хрен пойми что)
Нет, указатель указывает на тот static объект (см. пост #18)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.01.2012, 23:18
Помогаю со студенческими работами здесь

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

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

Динамическая память
в чем ошибка #include &lt;iostream&gt; #include &quot;conio.h&quot; using namespace std; class{A int a; double b; char s; }

Динамическая память с++
Как использовать динамическую память в с++

Динамическая память [new]
Если записать так: 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;


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Музыка, написанная Искусственным Интеллектом
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
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru