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

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

Войти
Регистрация
Восстановить пароль
 
 
edward_jonson
159 / 159 / 25
Регистрация: 23.02.2011
Сообщений: 392
#1

Память под объекты через new - C++

23.07.2012, 02:57. Просмотров 892. Ответов 18
Метки нет (Все метки)

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
#include <iostream>
 
class A
{
public:
    int my;
};
 
 
int main()
{
    A* a = new A();
    A* b = new A();
    A* c;
    A* d;
 
    A f;
 
    std::cout << a << std::endl
              << b << std::endl
              << c << std::endl
              << d << std::endl;
 
    std::cout << std::endl;
 
    delete a;
    delete b;
}
Куски памяти под a и b распределяются друг за другом, а под c и d совсем в разных местах. Из-за чего так? Из-за того, что a и b указывают на существующий в памяти объект, а c и d - нет? И желательно ли писать:
C++
1
2
    A* c = NULL;
    A* d = NULL;
Да и вообще, принципиальной разницы между
C++
1
2
    a->my = 4;
    f.my = 5;
нету, да?(Я понимаю, что в первом случае обращение идёт через указатель, а во втором напрямую.) И какой из этих вариантов наиболее часто используется в практике? Или здесь так же, как и в случае
C++
1
2
    int* s = new int(6);
    std::cout << *s;
в практике почти не встречается и указатель требуется только для создания массивов объектов?

ЗЫ: Есть ли отличие:
C++
1
2
3
A* a = new A;
//и
A* a = new A();
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.07.2012, 02:57
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Память под объекты через new (C++):

Динамичная память под объекты - C++
Правильно ли я заполняю поля объектов с помощю методов в динамическом массиве из объектов.Все работает, но правильно ли это? EXAM*...

Можно ли динамически выделить память под массив указателей, на объекты класса? - C++
Прошу прощения если не правильно назвал вопрос. Не знаю как правильно сформулировать. Можно ли строчку VisualizationTools* VT; заменить...

Динамическая память. Функции. Массивы .Объекты - C++
Всем привет. Возник следующий вопрос: 1.Когда в c++ из функции возвращается объект (экземпляр какого-то класса), то насколько мне...

Можно ли записывать объекты класса string в память, чтоб потом их прочитать? - C++
Создал класс, который содержит много объектов класса string, но что то не так как надо. В debug режиме удаётся прочитать и вывести, но...

Перераспределение памяти с new под объекты - C++
есть класс #include &lt;iostream&gt; #include &lt;string&gt; using namespace std; class tel_book { private: char *FIO; int count...

Выделение памяти под объекты классов - C++
Здравствуйте, начал недавно осваивать классы и вот у меня в голове все крутится один вопрос. Каким образом происходит выделение памяти...

18
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 04:53 #2
Цитата Сообщение от edward_jonson Посмотреть сообщение
A* c = NULL;
A* d = NULL;
Без этого, MSVC ошибку при выполнении выдаёт: обращение к неинициализированнной переменной в строках 21 и 22, если продолжить, то адреса: СССССССС, СССССССС. mingv пропускает и выдаёт: 0x100, 0x4016dd. Вывод: желательно писать, или, хотя бы не обращаться к переменным до инициализации.

Цитата Сообщение от edward_jonson Посмотреть сообщение
A* a = new A;
//и
A* a = new A()
Без разницы. Конструктор по умолчанию.

Цитата Сообщение от edward_jonson Посмотреть сообщение
Да и вообще, принципиальной разницы между
a->my = 4;
f.my = 5;
нету, да?(Я понимаю, что в первом случае обращение идёт через указатель, а во втором напрямую.) И какой из этих вариантов наиболее часто используется в практике?
Разница в том, что в первом случае указатель, а во втором объект. В практике используется тот, который нужен. К объекту -> не приделаешь. Другое дело, что первый пример можно записать двумя способами: a -> my = 4; или (*a).my = 4; Тут, действительно, принципиальной разницы нет. Пусть эксперты скажут, для хорошего стиля программирования, какой лучше ?

Цитата Сообщение от edward_jonson Посмотреть сообщение
Куски памяти под a и b распределяются друг за другом, а под c и d совсем в разных местах.
Тут нужно разделить понятия: память под переменные a, b, c, d (под указатели) и память под то, на что эти указатели указывают. У вас у коде, а и b содержат адреса в динамической области памяти, по которым находятся созданные объекты класса А, а с и d не на что не указывают, в них, по идее, "мусор" должен быть (поэтому разные компиляторы по разному и обрабатывают вывод их содержимого через cout <<). Чтобы узнать адреса самих переменных нужно написать:
C++
1
2
3
4
std::cout << &a << std::endl
              << &b << std::endl
              << &c << std::endl
              << &d << std::endl;
Под них память выделена подряд, и (если я неправ, пусть поправят) в стеке. Если же так написать:
C++
1
2
3
4
5
6
7
8
A* a = new A();
A* b = new A;
A c;
A d;
std::cout << a << std::endl
          << b << std::endl
          << &c << std::endl
          << &d << std::endl;
, то выведутся адреса динамической памяти, содержащиеся в a и b , и адреса объектов c и d, созданных в автоматической области памяти (в стеке).
2
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.07.2012, 10:46 #3
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от edward_jonson Посмотреть сообщение
ЗЫ: Есть ли отличие
есть:
для POD типов конструктор не вызывается т.е.
C++
1
2
int* a = new int; //значение a - мусор
int* b = new int(); //значение b == 0
3
edward_jonson
159 / 159 / 25
Регистрация: 23.02.2011
Сообщений: 392
23.07.2012, 15:06  [ТС] #4
Jupiter, ну а если в класс A добавить конструктор -
C++
1
2
3
4
5
6
class A
{
public:
    int my;
    A() : my(4){}
};
то уже разницы между
C++
1
A* s = new A();
и
C++
1
A* s = new A;
не будет, т.к. в обоих случаях будет вызываться пользовательский конструктор по умолчанию?
0
Somebody
2791 / 1602 / 147
Регистрация: 03.12.2007
Сообщений: 4,200
Завершенные тесты: 1
23.07.2012, 15:14 #5
Цитата Сообщение от alsav22 Посмотреть сообщение
К объекту -> не приделаешь.
Почему? Можно перегрузить operator->
1
edward_jonson
159 / 159 / 25
Регистрация: 23.02.2011
Сообщений: 392
23.07.2012, 16:25  [ТС] #6
Цитата Сообщение от alsav22 Посмотреть сообщение
Разница в том, что в первом случае указатель, а во втором объект. В практике используется тот, который нужен. К объекту -> не приделаешь. Другое дело, что первый пример можно записать двумя способами: a -> my = 4; или (*a).my = 4; Тут, действительно, принципиальной разницы нет. Пусть эксперты скажут, для хорошего стиля программирования, какой лучше ?
Да можно даже написать
C++
1
2
A a;
(&a)->my = 4;
Только не думаю, что кто-то будет)
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 21:41 #7
Цитата Сообщение от Jupiter Посмотреть сообщение
есть:
для POD типов конструктор не вызывается т.е.
C++
1
2
int* a = new int; //значение a - мусор
int* b = new int(); //значение b == 0
Что-то я здесь ни мусора, ни 0 не вижу...
0
Миниатюры
Память под объекты через new   Память под объекты через new  
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.07.2012, 21:43 #8
Цитата Сообщение от alsav22 Посмотреть сообщение
Что-то я здесь мусора не вижу...
C++
1
std::cout << *a << std::endl << *b << std::endl;
1
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 22:09 #9
Если так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
 
class A
{
public:
    int my;
    A(){std::cout << "K" << std::endl;}
};
 
int main()
{
    A* a = new A;
    A* b = new A();
    std::cout << a -> my << std::endl << b -> my << std::endl;
    std::cout << std::endl;
 
    delete a;
    delete b;
 
    system("pause");
    return 0;
}
, то конструктор вызывается, в my, и в a и в b мусор. Почему в b не 0, если должно *b == 0 ? Или это для int будет?
0
Jupiter
Каратель
Эксперт С++
6561 / 3982 / 227
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.07.2012, 22:21 #10
Цитата Сообщение от alsav22 Посмотреть сообщение
Почему в b не 0, если должно *b == 0 ? Или это для int будет?
инициализация POD-типов полностью возложена на программиста

Не по теме:

что такое POD-типы - в поиск, а лучше в последний стандарт, ЕМНИП там были внесены изменения в понятие POD-типов

1
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,165
Записей в блоге: 17
24.07.2012, 23:37 #11
Конструктор не правильный
C++
1
A():my(0){std::cout << "K" << std::endl;}
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.07.2012, 00:30 #12
Цитата Сообщение от Avazart Посмотреть сообщение
Конструктор не правильный
C++
1
A():my(0){std::cout << "K" << std::endl;}
Так и задумано было. Я тут другое выяснял. Jupiter, написал, что если так:
int* a = new int; //значение a - мусор
int* b = new int(); //значение b == 0
, т.е. память, на которую указывает b, будет заполнена 0 и конструктор не будет вызываться. Вот я и проверил для класса. std::cout << "K" << std::endl; это только, чтобы проверить срабатывает конструктор или нет, а my специально неинициализировал. Но дело тут ещё в том (Jupiter дальше написал), что есть POD, а что не POD.
0
xADMIRALx
67 / 61 / 1
Регистрация: 09.06.2012
Сообщений: 291
25.07.2012, 07:56 #13
хм,а я и не знал,спасибо юпитер

C++
1
2
3
4
5
6
7
8
9
        
        int *pr = new int;
    int *pr1 = new int();
 
    std::cout << "pr = " << *pr << std::endl;
    std::cout << "pr1 = " << *pr1 << std::endl;
 
    delete pr;
    delete pr1;
0
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,165
Записей в блоге: 17
25.07.2012, 10:31 #14
g++ вывод:
Код
pr = 0
pr1 = 0
А в чем разница?
Разве есть рахнзница между int и int() ?
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.07.2012, 11:23 #15
MSVC и mingv.
0
Миниатюры
Память под объекты через new   Память под объекты через new  
25.07.2012, 11:23
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.07.2012, 11:23
Привет! Вот еще темы с ответами:

Реализовать через тип данных структура при этом выделить память через new[] - C++
В таблице из 5 строк хранятся данные о товарах: наименование, цена, количество. Определить и вывести наименование товара, цена которого...

Выделение памяти с помощью new под объекты без вызова их конструкторов - C++
здравствуйте, корректен ли следующий код: myClass* pttr = static_cast&lt;myClass*&gt;(::operator new(5 * sizeof(myClass))); for (int i = 0; i...

Распределение памяти под объекты числовых типов. Не могу понять - C++
Может быть немного не в тему пишу, т.к. этот вопрос не относится конкретно к языку С++, просто столкнулся с этим, когда начал изучать этот...

Выделить память под переменную - C++
объявляет переменные и выделяет память под них как в с++ ?? обьявить переменную и выделить ей память?


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

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

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