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

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

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

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

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

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

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

в теле функции создается временный объект - строковая константа. затем создается еще один объект тоже строковая константа - для возврата. содержимое первой копируется полностью во вторую. затем все верно - первая умирает в теле функции а вторая возвращается.
0
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, умрет
0
AzaKendler
214 / 116 / 9
Регистрация: 30.05.2011
Сообщений: 1,772
28.01.2012, 21:59 #6
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
И никаких "НЕПРЕДСКАЗУЕМЫХ!!!!!" последствий я тут не наблюдаю =\\
ну они могут быть. поскольку используется "примитивное" копирование по умолчанию, то для неких сложных объектов данные могут быть утеряны

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

Добавлено через 1 минуту
Цитата Сообщение от Pavel.fromBy Посмотреть сообщение
Все же хотелось бы узнать, почему так!?
а почему не должно работать? на твой взгляд в этом примере
0
Paporotnik
383 / 227 / 7
Регистрация: 06.07.2011
Сообщений: 512
28.01.2012, 22:00 #7
"Память под строковые литералы выделяется статически, поэтому их возврат из функций безопасен" Б. Страуструп
1
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;
}
 
}
 
 
}
 
поясни при сложении и присваивании что умрет?
0
AnyOne697
134 / 106 / 5
Регистрация: 22.05.2010
Сообщений: 533
28.01.2012, 22:03 #9
Ну раз возврат безопасен, значит всё окей...

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

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

Не по теме:

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

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

Не по теме:

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

0
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. Памятник тому, кто разберется и объяснит

Не по теме:

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

0
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;
}
по твоей просьбе в личном сообшении.

Ты создаешь временные копии объектов. Этого делать не надо, если этого явно не требуется.
В твоем примере временные объекты будут создаваться и уничтожаться отнимая время.
Просто так "от захотелось" следует избегать такого явления используя ссылки или указатели.
0
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
0
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 минуты
ЗЫ:
Я искренне надеюсь что сий пример помог чем либо.
0
28.01.2012, 23:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2012, 23:05
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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