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

Как создать объект в новой куче? - C++

Восстановить пароль Регистрация
 
 
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 13:13     Как создать объект в новой куче? #1
VisualStudio 2012, Win7x64Prof.

Пробую выделить память в куче, а потом с помощью формы "Placement new" разместить в ней объект.

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
class MyClass
{
public:
    int x;
 
    MyClass()
    {
        x=0;
    }
 
    ~MyClass()
    {
        x=1;
    }
};
 
void MyFunc(const HANDLE hHeap)
{
//выделяем память, все ок
MyClass* placementMemory = (MyClass*) HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY, sizeof(MyClass));
 
//пробуем разместить в этой памяти новый объект, ошибка!
MyClass* cl = new (placementMemory) MyClass();
}
Последняя строчка содержит две ошибки (подчеркивания красной линией): при наведении мышью на "placementMemory" всплывает подсказка: "Error: требуется спецификатор типа", а при наведении на "MyClass"- "Error: требуется точка с запятой ";"";

Как осилить гидру?
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 13:21     Как создать объект в новой куче? #2
может #include <new> отсутствует, может еще что. полностью ошибки сюда вставте.
вот в 2005 студии компилится:
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
32
33
34
35
36
37
38
#include <new>
#include <iostream>
 
class MyClass
{
public:
    int x;
 
    MyClass()
    {
        std::cout << "MyClass" << std::endl;
        x=666;
    }
 
    ~MyClass()
    {
        std::cout << "~MyClass" << std::endl;
        x=1;
    }
 
    void foo()
    {
        std::cout << "x = " << x << std::endl;
    }
};
 
int main()
{
    char buffer[sizeof(MyClass)];
    MyClass* ptr = new (buffer) MyClass();
    ptr->foo();
    ptr->~MyClass();
 
    MyClass* specifiedBuffer = (MyClass*) buffer;
    MyClass* ptr2 = new (specifiedBuffer) MyClass(); // тоже ок
 
    return 0;
}
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 13:31  [ТС]     Как создать объект в новой куче? #3
#include <new> -присутствует,

а ошибка малоинформативна: "error C2061: синтаксическая ошибка: идентификатор "placementMemory"".
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 13:34     Как создать объект в новой куче? #4
вот один в один скопипастил код и все компилится. у вас там точно такой же код, или это упрощенная для форума версия?
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 14:18  [ТС]     Как создать объект в новой куче? #5
Цитата Сообщение от DU Посмотреть сообщение
вот один в один скопипастил код и все компилится. у вас там точно такой же код, или это упрощенная для форума версия?
Код является абсолютной копией (для верности закомментировал что было и вставил с форума- та же реакция). MFC проект, модуль диалога.

Добавлено через 3 минуты
Попробовал ваш вариант- ошибки абсолютно те же:
2 штуки на строке "MyClass* ptr = new (buffer) MyClass();"

и еще две на строке "MyClass* ptr2 = new (specifiedBuffer) MyClass(); // тоже ок"
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 14:20     Как создать объект в новой куче? #6
ну хз тогда. вот тут все тоже ок: http://liveworkspace.org/code/26ddfP$1
еще раз: выложите сюда полностью список ошибко. строчки, тексты, коды ошибок. возможно в сети что-нибудь есть на эту тему и по кодам можно найти. так гадать сложно.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.01.2013, 14:52     Как создать объект в новой куче? #7
IvanPryamoy,
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
HeapAlloc(hHeap,
Как hHeap получили?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.01.2013, 14:57     Как создать объект в новой куче? #8
HeapCreate(), не?
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 15:08  [ТС]     Как создать объект в новой куче? #9
Ошибка оказалась весьма забавной: в модуле диалога формы MFC-проекта есть такие строки:

C++
1
2
3
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
Так вот этот самый DEBUG_NEW не поддерживает плэйсмент размещения. Как же тогда тестировать мою программу? Можно закоментировать эту чертову конструкцию с переопределением new?

Если использовать Release- конфигурацию, то все отлично запускается и работает.

http://stackoverflow.com/questions/4...t-does-it-mean

Добавлено через 8 минут
Может есть какой-то другой способ размещения объектов в произвольной куче (без использования placement new)?
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.01.2013, 15:23     Как создать объект в новой куче? #10
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
Может есть какой-то другой способ размещения объектов в произвольной куче (без использования placement new)?
memcpy если у вас в конструкторе ничего сложного нет.
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 15:32  [ТС]     Как создать объект в новой куче? #11
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Насколько я понял этот самый DEBUG_NEW нужен только для того, чтобы легче найти место утечки памяти (сама утечка и без этого нагромождения будет видна). Другими словами это дополнительный сервис, который позволит легче отлаживать при наличии утечек (а при отсутствии таковых- лишняя надстройка).

C++
1
#define DEBUG_NEW new(THIS_FILE, __LINE__)
http://www.firststeps.ru/mfc/steps/r.php?228

Так что решил закоментировать строки:

C++
1
2
3
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
и жить счастливо (поскольку утечек у меня нет- на то они и кучи, чтобы разом всю память освобождать).

Может кто-то раскритиковать мои смелые утверждения?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 15:42     Как создать объект в новой куче? #12
утечки - это не только не освобождение памяти. это еще и неотработанные деструкторы.
и если память системе все-таки вернуть можно, то вот нужные деструкторы таким макаром не вызовутся.
так что тут нужно быть осторожным.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.01.2013, 15:46     Как создать объект в новой куче? #13
Цитата Сообщение от DU Посмотреть сообщение
это еще и неотработанные деструкторы.
В смысле?

Цитата Сообщение от DU Посмотреть сообщение
и если память системе все-таки вернуть можно, то вот нужные деструкторы таким макаром не вызовутся.
А вы точно видели объявление этого макроса?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 15:56     Как создать объект в новой куче? #14
в том смысле, если объекты создавать в заранее подготовленном пуле и потом его убивать - то это как бы нет утечки памяти. да, это так. но в этой памяти создавались объекты и важно, чтобы их деструкторы вызывались.
так вот, просто возвращение памяти системе не вызовет эти деструкторы. а значит что-то может утечь, попимо памяти. например синзронизирующие объекты остались в занятом состоянии (освобождаются в теле деструтора), дескрипторы файлов или еще чего-то тоже не освобождены (освобождаются в теле деструктора) и т.д.
Ну и я не понял, как на это повлияет этот макрос. Автор ведь его закомментировал и создает объекты в заранее выделенном буфере памяти.
вот такой классик тоже приведет к утечке, если деструктор не позовется:
C++
1
2
3
4
class Class
{
  std::string str;
}
ведь буффер, выделяемый внутри std::string создается не в пуле, а в общем месте до тех пор, пока там аллокатор нужный не подсунут или оператор new не перепишут или хз что еще не сделают.
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 16:19  [ТС]     Как создать объект в новой куче? #15
Цитата Сообщение от DU Посмотреть сообщение
C++
1
2
3
4
class Class
{
  std::string str;
}
А можно как-то потоку указать его кучу, чтобы он все объекты создавал только в ней? Тогда все дополнительные телодвижения (выделение памяти в куче, размещение там каждого объекта) сразу будут не нужны.

Такое бывает?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.01.2013, 16:25     Как создать объект в новой куче? #16
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
Такое бывает?
Бывает. Во всяких языках более высокого уровня, где за вас создана куча, а её хендл засунут в thread-local storage, а new растолковано, что нужную кучу надо брать из TLS. А так ручками это сделать надо.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 16:30     Как создать объект в новой куче? #17
я бы не сказал что все так просто. указал и забыл. пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Foo
{
   std::string str;
};
 
// Thread1
//создание к контексте потока 1
Foo* foo = new Foo(); // допустим это сработало так, что разместилось в специальном буфере.
 
// Thread2
// работаем в контексте второго потока, у него есть ссылка на объект, который создался в контексте первого
foo->str.resize(100);
// вот тут пересоздается буфер внутри строки, пересоздается в контексте второго потока,
// который размещает динамические объекты как-то по другому. Но перед этим ему нужно
// удалить предыдущий буфер, который был создан в контексте первого. И сделать это нужно корректно.
// Как тут быть? Следить за всем и корректно выделять\освобождать? Как-то все достаточно сложно получается.
Igor3D
791 / 408 / 33
Регистрация: 01.10.2012
Сообщений: 2,061
19.01.2013, 16:33     Как создать объект в новой куче? #18
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
А можно как-то потоку указать его кучу, чтобы он все объекты создавал только в ней? Тогда все дополнительные телодвижения (выделение памяти в куче, размещение там каждого объекта) сразу будут не нужны.
Такое бывает?
Ну "подобное" нередко приходится делать. Но телодвижений там раз в 10 больше. Код не знает в какой нитке исполняется, может в неск одновременно
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 16:36  [ТС]     Как создать объект в новой куче? #19
Цитата Сообщение от DU Посмотреть сообщение
я бы не сказал что все так просто. указал и забыл. пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct Foo
{
   std::string str;
};
 
// Thread1
//создание к контексте потока 1
Foo* foo = new Foo(); // допустим это сработало так, что разместилось в специальном буфере.
 
// Thread2
// работаем в контексте второго потока, у него есть ссылка на объект, который создался в контексте первого
foo->str.resize(100);
// вот тут пересоздается буфер внутри строки, пересоздается в контексте второго потока,
// который размещает динамические объекты как-то по другому. Но перед этим ему нужно
// удалить предыдущий буфер, который был создан в контексте первого. И сделать это нужно корректно.
// Как тут быть? Следить за всем и корректно выделять\освобождать? Как-то все достаточно сложно получается.
Ну а если потоки совсем независимы (нет у них никакого взаимодействия: каждый обсчитывает свой файл независимых данных)? Ведь лучше сделать так, чтобы потом не мучиться с отладкой, раздумывая "где тут ошибка?"

Как создать "обертки памяти" в виде отдельных куч для потоков?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.01.2013, 16:41     Как создать объект в новой куче?
Еще ссылки по теме:

C++ Как создать объект класса в динамической памяти?
Как создать объект класса в потоке? C++
C++ Создать объект стек и создать объект очередь с перегруженными операциями

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

Или воспользуйтесь поиском по форуму:
Igor3D
791 / 408 / 33
Регистрация: 01.10.2012
Сообщений: 2,061
19.01.2013, 16:41     Как создать объект в новой куче? #20
Цитата Сообщение от DU Посмотреть сообщение
// вот тут пересоздается буфер внутри строки, пересоздается в контексте второго потока,
// который размещает динамические объекты как-то по другому. Но перед этим ему нужно
// удалить предыдущий буфер, который был создан в контексте первого. И сделать это нужно корректно.
// Как тут быть? Следить за всем и корректно выделять\освобождать? Как-то все достаточно сложно получается.
Все гораздо хуже. std::string - это "корова", причем без требований атомарности
C++
1
2
3
4
string s1("abc");
string s2 = s1;
((char *) s2.c_str())[0] = 'x';
count << s1 << std::endl << s2;
Увидите неожиданный s1
Yandex
Объявления
19.01.2013, 16:41     Как создать объект в новой куче?
Ответ Создать тему
Опции темы

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