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

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

Восстановить пароль Регистрация
 
edward_jonson
 Аватар для edward_jonson
157 / 157 / 25
Регистрация: 23.02.2011
Сообщений: 388
23.07.2012, 02:57     Память под объекты через new #1
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();
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 04:53     Память под объекты через new #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, созданных в автоматической области памяти (в стеке).
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.07.2012, 10:46     Память под объекты через new #3
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от edward_jonson Посмотреть сообщение
ЗЫ: Есть ли отличие
есть:
для POD типов конструктор не вызывается т.е.
C++
1
2
int* a = new int; //значение a - мусор
int* b = new int(); //значение b == 0
edward_jonson
 Аватар для edward_jonson
157 / 157 / 25
Регистрация: 23.02.2011
Сообщений: 388
23.07.2012, 15:06  [ТС]     Память под объекты через new #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;
не будет, т.к. в обоих случаях будет вызываться пользовательский конструктор по умолчанию?
Somebody
2770 / 1583 / 141
Регистрация: 03.12.2007
Сообщений: 4,139
Завершенные тесты: 1
23.07.2012, 15:14     Память под объекты через new #5
Цитата Сообщение от alsav22 Посмотреть сообщение
К объекту -> не приделаешь.
Почему? Можно перегрузить operator->
edward_jonson
 Аватар для edward_jonson
157 / 157 / 25
Регистрация: 23.02.2011
Сообщений: 388
23.07.2012, 16:25  [ТС]     Память под объекты через new #6
Цитата Сообщение от alsav22 Посмотреть сообщение
Разница в том, что в первом случае указатель, а во втором объект. В практике используется тот, который нужен. К объекту -> не приделаешь. Другое дело, что первый пример можно записать двумя способами: a -> my = 4; или (*a).my = 4; Тут, действительно, принципиальной разницы нет. Пусть эксперты скажут, для хорошего стиля программирования, какой лучше ?
Да можно даже написать
C++
1
2
A a;
(&a)->my = 4;
Только не думаю, что кто-то будет)
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 21:41     Память под объекты через new #7
Цитата Сообщение от Jupiter Посмотреть сообщение
есть:
для POD типов конструктор не вызывается т.е.
C++
1
2
int* a = new int; //значение a - мусор
int* b = new int(); //значение b == 0
Что-то я здесь ни мусора, ни 0 не вижу...
Миниатюры
Память под объекты через new   Память под объекты через new  
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.07.2012, 21:43     Память под объекты через new #8
Цитата Сообщение от alsav22 Посмотреть сообщение
Что-то я здесь мусора не вижу...
C++
1
std::cout << *a << std::endl << *b << std::endl;
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
23.07.2012, 22:09     Память под объекты через new #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 будет?
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
23.07.2012, 22:21     Память под объекты через new #10
Цитата Сообщение от alsav22 Посмотреть сообщение
Почему в b не 0, если должно *b == 0 ? Или это для int будет?
инициализация POD-типов полностью возложена на программиста

Не по теме:

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

Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
24.07.2012, 23:37     Память под объекты через new #11
Конструктор не правильный
C++
1
A():my(0){std::cout << "K" << std::endl;}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.07.2012, 00:30     Память под объекты через new #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.
xADMIRALx
 Аватар для xADMIRALx
66 / 60 / 1
Регистрация: 09.06.2012
Сообщений: 291
25.07.2012, 07:56     Память под объекты через new #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;
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
25.07.2012, 10:31     Память под объекты через new #14
g++ вывод:
Код
pr = 0
pr1 = 0
А в чем разница?
Разве есть рахнзница между int и int() ?
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.07.2012, 11:23     Память под объекты через new #15
MSVC и mingv.
Миниатюры
Память под объекты через new   Память под объекты через new  
Jupiter
Каратель
Эксперт C++
6543 / 3963 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
25.07.2012, 11:38     Память под объекты через new #16
Цитата Сообщение от Avazart Посмотреть сообщение
А в чем разница?
Разве есть рахнзница между int и int() ?
8-я глава черновика последнего стандарта, подраздел инициализаторы
8.5
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
чуть выше пояснение
To value-initialize an object of type T means:
— if T is a (possibly cv-qualified) class type (Clause 9) with a user-provided constructor (12.1), then the
default constructor for T is called (and the initialization is ill-formed if T has no accessible default
constructor);
— if T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object
is zero-initialized and, if T’s implicitly-declared default constructor is non-trivial, that constructor is
called.
— if T is an array type, then each element is value-initialized;
— otherwise, the object is zero-initialized.
и ещё чуть выше
To zero-initialize an object or reference of type T means:
— if T is a scalar type (3.9), the object is set to the value 0 (zero), taken as an integral constant expression,
converted to T;103
— if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class
subobject is zero-initialized;
— if T is a (possibly cv-qualified) union type, the object’s first non-static named data member is zero-
initialized;
— if T is an array type, each element is zero-initialized;
— if T is a reference type, no initialization is performed.
edward_jonson
 Аватар для edward_jonson
157 / 157 / 25
Регистрация: 23.02.2011
Сообщений: 388
25.07.2012, 16:32  [ТС]     Память под объекты через new #17
ВЫВОД:
Если в классе A имеется любой пользовательский конструктор по умолчанию, то разницы между
C++
1
A* a = new A();
и
C++
1
A* a = new A;
нет (либо в обоих классах в полях будет мусор, либо то, чем поля инициализированы в конструкторе по умолчанию), если же в классе конструктора по умолчанию нет, то в случае
C++
1
A* a = new A();
поля будут инициализированы 0, а в случае
C++
1
A* a = new A;
там будет мусор. (Со стандартными типами данных так же, как и с классами без конструктора по умолчанию).
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
25.07.2012, 16:41     Память под объекты через new #18
Думаю несовсем так.
Зависит от того каким будет класс POD - ом или нет, а на это влияет не только наличие конструктора.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.07.2012, 23:40     Память под объекты через new
Еще ссылки по теме:

C++ Можно ли записывать объекты класса string в память, чтоб потом их прочитать?
C++ Выделите-ка под массив память размером 32 ГБ
Как сделать программу через объекты? C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
25.07.2012, 23:40     Память под объекты через new #19
Цитата Сообщение от edward_jonson Посмотреть сообщение
если же в классе конструктора по умолчанию нет
К POD-типам относятся:
все встроенные арифметические типы (включая wchar_t и bool);
энумераторы, т.е. типы, объявленные с помощью ключевого слова enum;
все указатели;
POD-структуры (struct или class) и POD-объединения (union), которые удовлетворяют всем нижеприведенным требованиям:
не содержат пользовательских конструкторов, деструктора или копирующего оператора присваивания (копирующий оператор присваивания – это такой нешаблонный нестатический operator=, у которого есть строго один параметр типа X, X&, const X&, volatile X& или const volatile X&, где X – тип рассматриваемой структуры или объединения);
не имеют базовых классов;
не содержат виртуальных функций;
не содержат защищенных (protected) или закрытых (private) нестатических членов данных;
не содержат нестатических членов данных не-POD-типов (или массивов из таких типов), а также ссылок.
Соответственно, все оставшиеся объектные типы являются не-POD-типами.
Примечание: наличие квалификаторов const и volatile не влияет на «POD-овость» типа.
Если так:
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(){}
};
 
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;
}
, то класс А уже не POD, и в b -> my мусор.
Yandex
Объявления
25.07.2012, 23:40     Память под объекты через new
Ответ Создать тему
Опции темы

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