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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
VoltDeMar
16 / 16 / 0
Регистрация: 05.06.2012
Сообщений: 1,015
#1

Malloc vs new - C++

08.07.2015, 14:54. Просмотров 1219. Ответов 33
Метки нет (Все метки)

Здравствуйте.

Вникаю в ручное управление памятью. Абзац из книги "C++ для профессионалов" не совпадает с моим представлением использования объектов. Тут написано:

C++
1
2
Foo* myFoo = {Foo*}malloc(sizeof(Foo));
Foo* myOtherFoo = new Foo();
После выполнения этих строк кода как переменная myFoo, так и переменная myOtherFoo будут указывать на области памяти в "куче", которые имею достаточный размер для хранения объекта Foo. К членам данных и методам объекта Foo можно получить доступ с помощью обоих указателей. Различие между ними состоит в том, что объект Foo, адресуемый указателем myFoo, не является, по сути, объектом, поскольку он не был построен.

Из других источников прочел что malloc не вызывает конструктор.

Но как это удается получить доступ к членам данных и методам объекта которого не существует. И образуется в памяти после выполнения malloc ?

Или это значит что после выделения памяти при помощи malloc нужно вручную вызывать конструктор?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.07.2015, 14:54     Malloc vs new
Посмотрите здесь:

C++ malloc/realloc
malloc, realloc C++
malloc в С++ C++
malloc() C++
C++ Ошибка с malloc
C++ malloc vs new
new на malloc C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
MansMI
1134 / 931 / 239
Регистрация: 08.01.2012
Сообщений: 3,362
08.07.2015, 15:00     Malloc vs new #2
все доступно, но если конструктор рандомно или еще как заполняет поля, то у *myFoo они левые, не помню чистит ли память malloc, если так то нулевые
Croessmah
Модератор
Эксперт CЭксперт С++
12887 / 7273 / 810
Регистрация: 27.09.2012
Сообщений: 17,972
Записей в блоге: 2
Завершенные тесты: 1
08.07.2015, 15:10     Malloc vs new #3
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Из других источников прочел что malloc не вызывает конструктор.
он даже про них не знает. Это функция из библиотеки C, а не C++
VoltDeMar
16 / 16 / 0
Регистрация: 05.06.2012
Сообщений: 1,015
08.07.2015, 15:12  [ТС]     Malloc vs new #4
Цитата Сообщение от MansMI Посмотреть сообщение
все доступно, но если конструктор рандомно или еще как заполняет поля, то у *myFoo они левые, не помню чистит ли память malloc, если так то нулевые
о каком конструкторе речь, malloc вызывает какие то конструкторы? Как происходит доступ к методам класса без объекта, что расположено в памяти?
MansMI
1134 / 931 / 239
Регистрация: 08.01.2012
Сообщений: 3,362
08.07.2015, 15:31     Malloc vs new #5
malloc не вызывает какие то конструкторы
DrOffset
6854 / 4065 / 927
Регистрация: 30.01.2014
Сообщений: 6,862
08.07.2015, 15:35     Malloc vs new #6
Цитата Сообщение от VoltDeMar Посмотреть сообщение
malloc вызывает какие то конструкторы?
Нет.
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Как происходит доступ к методам класса без объекта, что расположено в памяти?
По сути, функция класса может быть реализована так:
C++
1
<тип возвращаемого значения> Foo_method(Foo* this, <аргументы>);
Т.е. компилятору все равно (если дело не касается виртуальных вызовов), что память, которая отведена под объект, не инициализирована. Он сгенерирует код, где указатель на эту память передается в эту функцию первым скрытым параметром при вызове и все.
Другое дело, что код, который должен работать внутри функции-члена, может зависеть от состояния объекта, которое задается конструктором. Иными словами программа будет работать, но некорректно.

Вот это из цитаты:
Цитата Сообщение от VoltDeMar
Различие между ними состоит в том, что объект Foo, адресуемый указателем myFoo, не является, по сути, объектом, поскольку он не был построен.
И вот это
Цитата Сообщение от VoltDeMar
прочел что malloc не вызывает конструктор.
Об одном и том же. "Объект не был построен" == "не был вызван конструктор".

Вот тебе код для размышления:
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
#include <new>
#include <iostream>
 
class A { 
public:
    A() : v(10) {}
 
    void foo() { std::cout << v << std::endl;  }
private:
    int v;
};
 
int main()
{
    char memory[sizeof(A)]; // Пока что опустим детали насчет выравнивания
 
    A * p = (A*)memory;
 
    p->foo();
 
    ::new(p) A();
 
    p->foo();
};
Tulosba
:)
Эксперт С++
4391 / 3234 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
08.07.2015, 15:38     Malloc vs new #7
VoltDeMar, malloc выделяет сырую память, указанного размера.
new выделяет память, а потом вызывает конструктор типа.
Если тип является POD (plain old data), то различий в вызовах new и malloc практически нет.
VoltDeMar
16 / 16 / 0
Регистрация: 05.06.2012
Сообщений: 1,015
08.07.2015, 16:47  [ТС]     Malloc vs new #8
Цитата Сообщение от DrOffset Посмотреть сообщение
По сути, функция класса может быть реализована так:
Хочется узнать как это реализуется в реальности.
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот тебе код для размышления:
Что я должен понять из этого кода?

Добавлено через 9 минут
на сplusplus.com написано: The content of the newly allocated block of memory is not initialized, remaining with indeterminate values.

Как происходит поэтапно доступ к членам класса?
DrOffset
6854 / 4065 / 927
Регистрация: 30.01.2014
Сообщений: 6,862
08.07.2015, 17:08     Malloc vs new #9
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Хочется узнать как это реализуется в реальности.
Как показал, так и реализуется.

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Что я должен понять из этого кода?
То, что любой блок памяти можно представить как любой объект и работать с ним так, как будто бы он там есть.
С этой точки зрения все равно есть ли в объекте конкретные значения или там мусор лежит. Главное, что есть память.

Цитата Сообщение от VoltDeMar Посмотреть сообщение
Как происходит поэтапно доступ к членам класса?
Выше показал. Вот есть класс А:
C++
1
2
3
4
5
6
class A {
public:
    int v;
    
    A() : v(10) {}
};
Добавим ему функцию foo:
C++
1
2
3
4
5
6
7
8
9
10
class A {
public:
    int v;
 
    A() : v(10) {}
 
    void foo() {
         printf("value: %d\n", v);
    }
};
Что в реальности будет сделано? Компилятором будет создана такая функция:
C++
1
2
3
    void foo(A * this) {
         printf("value: %d\n", this->v);
    }
Теперь создадим объект через new. Выражение new включает выделенеи памяти и инициализацию объекта. Выделение памяти делается посредством operator new (который можно перегружать), будет выделена память sizeof(A). А он, в свою очередь, может быть реализован как обычный malloc. Итого:
C++
1
A * p = (A*)malloc(sizeof(A));
Теперь проводим инициализацию (вызываем конструктор):
C++
1
::new(p) A(); // здесь v задается значение 10
Здесь будет вызван конструктор для памяти, которую выделил malloc.
Затем сделаем вызов функции foo, который по сути является вот чем:
C++
1
foo(p); // p->foo();
Тут все понятно?
Теперь выкинем вызов конструктора из этой цепочки. Что изменилось? У v значение не 10, а какое-то случайное, которые было в памяти до ее использования в аллокации. И printf в foo выведет это число. Больше ничего не поменялось.

Никакие структуры данных, отвечающие на строение классов в рантайме не сохраняются (статически типизированный, компилируемый язык). Есть только память, регистры и смещения в памяти, которые генерирует компилятор, строя машинный код. Если мы в коде написали, что, вот этот блок памяти - имеет тип A, то и код будет генерироваться таким образом, чтобы отвечать принятым для А (размеры данных, смещения полей от начала блока, отступы для выравнивания и т.д.) соглашениям (это называется ABI).
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6411 / 3050 / 300
Регистрация: 04.12.2011
Сообщений: 8,255
Записей в блоге: 3
08.07.2015, 18:38     Malloc vs new #10
DrOffset, похоже что ТС почти понял, что методы не хранятся в объекте и вот-вот поймет.
Ну то есть на неинициализированном объекте можно вызвать метод (он как код принадлежит типу), а данные в этом методе будут мусором и результат непредсказуем. Если я понимаю правильно.
Evg
Эксперт CАвтор FAQ
17408 / 5646 / 354
Регистрация: 30.03.2009
Сообщений: 15,451
Записей в блоге: 26
08.07.2015, 20:24     Malloc vs new #11
Цитата Сообщение от VoltDeMar Посмотреть сообщение
Из других источников прочел что malloc не вызывает конструктор.
Но как это удается получить доступ к членам данных и методам объекта которого не существует. И образуется в памяти после выполнения malloc ?
Ты допускаешь стандартную ошибку, полагая, что конструктор занимается выделением памяти. Это не так. Конструктор занимается исключительно инициализацией полей в объекте, для которого память уже выделена. Просто new делает сразу две вещи - выделяет память (по сути malloc) и запускает конструктор. Подробнее можешь почитать тут: http://www.cyberforum.ru/blogs/18334/blog103.html
-=ЮрА=-
Заблокирован
Автор FAQ
08.07.2015, 20:50     Malloc vs new #12
malloc как и new выделяет память, отличие в том что new кидает exception(собственно поэтому маллок нельзя использовать в плюсовых программах). Выше на прау постов человек пытался подстроить к алоцирвоанию placement new это отдельная тема и для простой структуры или типа разницы в аллоцировании хоть будет нью хоть маллок не будет никакой.

Добавлено через 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
#include <iostream>
using namespace std;
 
void* operator new(size_t size) {
    return malloc(size);
}
 
void operator delete(void* ptr) {
  free(ptr);
}
 
class cTest{
    protected :
    size_t v;
    public:
    cTest(){
        v = 100;
    }
    size_t get_v(){return v;}
};
 
int main(){
    cTest * ptr = new cTest();
    cout<<ptr->get_v()<<endl;
    return 0;
}
http://ideone.com/lfevfL
И честное слово мне уже на форуме надоел бред мол new отличается от malloc (кроме ексепшина ничем, а если вы пишете под ВИН то поглядите на СРТ дебаг память - удивитесь вообще).

Не по теме:

Есть new есть placement new не мешайте понятния чёрт побери.

Kastaneda
Форумчанин
Эксперт С++
4470 / 2832 / 224
Регистрация: 12.12.2009
Сообщений: 7,202
Записей в блоге: 1
Завершенные тесты: 1
08.07.2015, 21:07     Malloc vs new #13
Вот это еще можно почитать. Писал правда 2 года назад, сейчас бы по-другому написал, но переписывать лень

Добавлено через 36 секунд
Цитата Сообщение от Kastaneda Посмотреть сообщение
сейчас бы по-другому написал
В статье все правильно, просто сейчас бы стилистически по-другому материал преподнес.
DrOffset
6854 / 4065 / 927
Регистрация: 30.01.2014
Сообщений: 6,862
08.07.2015, 21:48     Malloc vs new #14
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Выше на прау постов человек пытался подстроить к алоцирвоанию placement new
Я ничего не пытался. Считай, что это был псевдокод. Напрямую к placement new здесь не имеет смысла обращаться. Просто в С++ нет синтаксиса для отдельного вызова конструктора для заданной памяти, кроме как с использованием placement new.
В общем здесь это не существенно. ТСу непонятно как можно вызвать метод для неинициализированного объекта, а пример показывал что разницы между инициализированной памятью объекта и неинициализированной нет, с точки зрения вызова невиртуального метода.
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6411 / 3050 / 300
Регистрация: 04.12.2011
Сообщений: 8,255
Записей в блоге: 3
08.07.2015, 22:50     Malloc vs new #15
Kastaneda, а разве между функцией и выражением есть разница? Даже функция возвращающая значение типа void является выражением. Конструктор не укладывается в определение функции. Метод может ничего не возвращать (конструктор/деструктор) то есть не быть выражением.
Есть глобальная операторная функция new и операторная же функция-член. Если последняя определена (перегружен глобальный оператор) то к глобальному можно обратиться с помощью оператора разрешения ::
А перегрузить-то можно всяко же? Можно сделать что бы он не только конструктор не вызывал, но и память не выделял. Печатал на экране "бла-бла-бла" и всё. Это ничего не доказывает. Вот пример, где параметр задан, тоже чтобы компилятор скушал, но и память выделяется и конструктор запускается. Хотя это конечно не обязательно. Перегрузить можно всё что перегружается. Остальное вопрос совести и доброй воли.
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> 
using namespace std;
 
struct A{
int a;
A():a(0){}
A(int a_):a(a_){}
 
void * operator new(size_t){
cout<<"operator new"<<endl;
return ::new A;
}
 
};
int main()
{
A* p = new A(10);
cout<<p->a;
cout<<endl;
    system("pause");
return 0;
}
Evg
Эксперт CАвтор FAQ
17408 / 5646 / 354
Регистрация: 30.03.2009
Сообщений: 15,451
Записей в блоге: 26
08.07.2015, 23:00     Malloc vs new #16
Цитата Сообщение от IGPIGP Посмотреть сообщение
Kastaneda, а разве между функцией и выражением есть разница?
Я так понял, что смысл статьи в том, что в языке есть две разные сущности "new" и "operator new". Но т.к. в обоих сущностях используется одно и то же слово new, то начинающие не видят разницу между ними. При этом в русскоязычной литературе первое описывается как "оператор new" (а правильное название "выражение new" попросту режет слух), что может привести к заблуждению, что речь идёт об "operator new"
Croessmah
Модератор
Эксперт CЭксперт С++
12887 / 7273 / 810
Регистрация: 27.09.2012
Сообщений: 17,972
Записей в блоге: 2
Завершенные тесты: 1
08.07.2015, 23:06     Malloc vs new #17
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Evg Посмотреть сообщение
При этом в русскоязычной литературе первое описывается как "оператор new"
в русскоязычной литературе почти всё описывается как "оператор".
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6411 / 3050 / 300
Регистрация: 04.12.2011
Сообщений: 8,255
Записей в блоге: 3
08.07.2015, 23:11     Malloc vs new #18
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Evg Посмотреть сообщение
Я так понял, что смысл статьи в том, что в языке есть две разные сущности "new" и "operator new".
В языке есть глобальная операторная функция new и возможность перегрузки данной функции-оператора в классе.
Так же можно бы написать: "В языке есть глобальный оператор "+" и возможность перегрузки данного оператора в классе."
Функция оператор new возвращает указатель и поэтому в тексте её всегда можно назвать выражением, тут нет и не может быть разницы. А перегрузить можно так, что она на себя не будет похожа. Это да. Ну и что? В языке можно тако написать... Как на заборе. Но это же не значит что это оно и есть?
DrOffset
6854 / 4065 / 927
Регистрация: 30.01.2014
Сообщений: 6,862
08.07.2015, 23:24     Malloc vs new #19
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от IGPIGP Посмотреть сообщение
Функция оператор new возвращает указатель и поэтому в тексте её всегда можно назвать выражением, тут нет и не может быть разницы.
Дело в том, что в стандарте про это написано совершенно однозначно.
5.3.4/8
A new-expression may obtain storage for the object by calling an allocation function (3.7.4.1).
If the new-expression terminates by throwing an exception, it may release storage by calling a deallocation function (3.7.4.2).
If the allocated type is a non-array type, the allocation function’s name is operator new and
the deallocation function’s name is operator delete. If the allocated type is an array type, the allocation
function’s name is operator new[] and the deallocation function’s name is operator delete[] . [ Note: an
implementation shall provide default definitions for the global allocation functions (3.7.4, 18.6.1.1, 18.6.1.2).
A C++ program can provide alternative definitions of these functions (17.6.4.6) and/or class-specific versions (12.5). — end note ]
Выделение курсивом и полужирным - оригинальное. Поэтому мы оперируем этими терминами именно так.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.07.2015, 23:46     Malloc vs new
Еще ссылки по теме:

C++ new vs malloc
new, malloc, C++
C++ Malloc / calloc
Malloc realloc и C++ C++
C++ New и malloc

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

Или воспользуйтесь поиском по форуму:
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
6411 / 3050 / 300
Регистрация: 04.12.2011
Сообщений: 8,255
Записей в блоге: 3
08.07.2015, 23:46     Malloc vs new #20
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от DrOffset Посмотреть сообщение
Поэтому мы оперируем этими терминами именно так
Я наверное вообще не в теме. Мне показалось, что я везде пишу операторная функция. Выделение курсивом из встречаемого в литературе. То есть не выдуманное. Оператор плюс, например, - оператор встроенный в язык (глобальный). Для встроенных типов для которых определён, может иметь разное значение. Ну и что? Можно его перегрузить для своего класса так, что это будет минус. Будет ли откровением поведать публике, что плюс это на самом деле не плюс?
Yandex
Объявления
08.07.2015, 23:46     Malloc vs new
Ответ Создать тему
Опции темы

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