Форум программистов, компьютерный форум 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)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 16:45  [ТС]     Как создать объект в новой куче? #21
Похоже мне придется для своих объектов переопределять опреатор new, а объектами C++ не пользоваться (я кстати, их и не использую. Тот же string заменяю на простые массивы wchar_t).

Последнее можно гарантировать невключением C++ заголовков в файлы.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Igor3D
792 / 409 / 33
Регистрация: 01.10.2012
Сообщений: 2,067
19.01.2013, 16:49     Как создать объект в новой куче? #22
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
Ну а если потоки совсем независимы (нет у них никакого взаимодействия: каждый обсчитывает свой файл независимых данных)? Ведь лучше сделать так, чтобы потом не мучиться с отладкой, раздумывая "где тут ошибка?"

Как создать "обертки памяти" в виде отдельных куч для потоков?
Ну раздумывать все равно придется А нужна ли Вам "куча" для каждой нитки? Часто бывает что нет, достаточно неск контейнеров. Выглядит напр так
C++
1
2
3
4
5
6
7
8
void MyCalc( int threadIndex )
{
 vector <int> & data = theData[threadIndex];
 ...
// или так (с указателем)
 if (!theData[threadIndex]) 
  theData[threadIndex] = new vector <int> (100);
}
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.01.2013, 16:52     Как создать объект в новой куче? #23
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
Как создать "обертки памяти" в виде отдельных куч для потоков?
Банальный пример:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>
#include <windows.h>
 
#define USE_TLS
 
#ifdef USE_TLS
DWORD g_heap_TLS_idx;
 
void InitTLS(void)
{
    g_heap_TLS_idx = TlsAlloc();
}
 
void FreeTLS(void)
{
    TlsFree(g_heap_TLS_idx);
}
 
void InitThreadHeap(void)
{
    HANDLE heap = HeapCreate(0, 0, 10 * 1024 * 1024);
    TlsSetValue(g_heap_TLS_idx, heap);
}
 
HANDLE GetThreadHeap(void)
{
    return TlsGetValue(g_heap_TLS_idx);
}
 
void FreeThreadHeap(void)
{
    HeapDestroy(GetThreadHeap());
}
 
void* operator new(size_t size)
{
    return HeapAlloc(GetThreadHeap(), 0, size);
}
 
void operator delete(void* ptr)
{
    HeapFree(GetThreadHeap(), 0, ptr);
}
#endif
 
DWORD WINAPI entry(LPVOID)
{
#ifdef USE_TLS
    InitThreadHeap();
#endif
 
    int *x = new int;
    std::cout << x << "\n";
    delete x;
 
#ifdef USE_TLS
    FreeThreadHeap();
#endif
}
 
int main(int argc, char *argv[])
{
#ifdef USE_TLS
    InitTLS();
#endif
 
    HANDLE thread[2];
    thread[0] = CreateThread(NULL, 0, entry, NULL, 0, NULL);
    thread[1] = CreateThread(NULL, 0, entry, NULL, 0, NULL);
    WaitForMultipleObjects(2, thread, TRUE, 60 * 1000);
 
#ifdef USE_TLS
    FreeTLS();
#endif
    return 0;
}
Если дефайн есть, то те инты в разных потоках создаются в разных кучах (адреса чёрти где разбросаны). Если нет, то в одной и той же (адреса рядом). Никакой синхронизации и т. п., так что выводит иногда криво.

Вот эти куски, что в ифдефах в main() и entry(), вообще должны автомагически вставляться кем-то, чтобы 100% не забыли всё создать и удалить. И чтоб не вызвали по два раза, и т. п.

(Естессно, кроме этого ещё масса приключений впереди: массивы, обработка ошибок, "какая-то падла переопределила вместо меня глобальный new и всё сломалось"...)
IvanPryamoy
247 / 1 / 1
Регистрация: 02.01.2013
Сообщений: 31
19.01.2013, 17:03  [ТС]     Как создать объект в новой куче? #24
Цитата Сообщение от Igor3D Посмотреть сообщение
Ну раздумывать все равно придется А нужна ли Вам "куча" для каждой нитки? Часто бывает что нет, достаточно неск контейнеров. Выглядит напр так
C++
1
2
3
4
5
6
7
8
void MyCalc( int threadIndex )
{
 vector <int> & data = theData[threadIndex];
 ...
// или так (с указателем)
 if (!theData[threadIndex]) 
  theData[threadIndex] = new vector <int> (100);
}
Спасибо, за пример, но данные очень большие (массивы по 100 млн. чисел, причем массивов несколько). Так что надо все-таки культурненько их разделить (почему я и задался этим вопросом. Ведь если было бы все так просто, как в вашем примере, то для меня надо было бы дурку вызывать )
Igor3D
792 / 409 / 33
Регистрация: 01.10.2012
Сообщений: 2,067
19.01.2013, 17:10     Как создать объект в новой куче? #25
Цитата Сообщение от IvanPryamoy Посмотреть сообщение
Спасибо, за пример, но данные очень большие (массивы по 100 млн. чисел, причем массивов несколько). Так что надо все-таки культурненько их разделить (почему я и задался этим вопросом. Ведь если было бы все так просто, как в вашем примере, то для меня надо было бы дурку вызывать )
У меня тоже гигабайтные данные, но никакого "разделения" я не делаю, т.к. не вижу что оно даст. Другое дело что vector (да и др контейнеры std) не годятся для таких данных. Но то уже др вопрос
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.01.2013, 17:15     Как создать объект в новой куче? #26
DU, что опасного в вашем примере так и не понял. Когда стэк будет чиститься деструктор для строки таки будет вызван.
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 17:42     Как создать объект в новой куче? #27
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 SimpleClass
{
   int x;
   int y;
};
 
 
{
   char buffer[sizeof(SimpleClass)];
   SimpleClass* ptr = new (buffer) SimpleClass();
   // тут что-то делаем.
   // тут не позвали деструктор. но память не утекла. дектруктор SimpleClass ничего интересного
   // не делает, а сам он размещен в буффере, который на стеке, который корректно уничножится.
   // вроде ничего не утекло.
}
 
{
   char buffer[sizeof(std::string)];
   std::string* ptr = new (buffer) std::string();
   ptr->resise(1000); // вот тут внутри строки выделяется буфер для хранения 1000 символов. и выделяется
                            // он не в буфере на стеке. его надо будет удалить. а делается это в деструкторе строки.
   // тут не позвали деструктор. и вот тут утекла та память, которую строка выделела для хранения 1000 символов
}
это я к тому, что выделять заранее кучу памяти и создавать там объекты и не звать для них деструкторы,
- это может быть чревато. если это делать осознанно - то ок.
go
Эксперт C++
3582 / 1362 / 128
Регистрация: 16.04.2009
Сообщений: 4,528
19.01.2013, 22:32     Как создать объект в новой куче? #28
Цитата Сообщение от DU Посмотреть сообщение
// тут не позвали деструктор. и вот тут утекла та память, которую строка выделела для хранения 1000 символов
Я вас не понимаю. Вы говорите очевидные вещи. Естественно надо сделать
C++
1
ptr->~string();
Я думал, что мы обсуждаем вот этот пост Как создать объект в новой куче?
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.01.2013, 22:42     Как создать объект в новой куче? #29
да нет. я рассуждал относительно этого сообщения:
Как создать объект в новой куче?
а конкретно:
и жить счастливо (поскольку утечек у меня нет- на то они и кучи, чтобы разом всю память освобождать).
т.е. жить счастливо просто вернув системе память не получится
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.01.2013, 11:19     Как создать объект в новой куче?
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
Igor3D
792 / 409 / 33
Регистрация: 01.10.2012
Сообщений: 2,067
20.01.2013, 11:19     Как создать объект в новой куче? #30
Цитата Сообщение от go Посмотреть сообщение
Я вас не понимаю. Вы говорите очевидные вещи. Естественно надо сделать
C++
1
ptr->~string();
Да как-то это "не выглядит хорошо" Вместо того чтобы "освободить все" мы начинаем "ловить блох" с каждым распределенным.

Др словами эта радость (освободить все) хороша только для POD структур, а что-то "выще травы" попрется делать внутренний new, в итоге себе дороже
Yandex
Объявления
20.01.2013, 11:19     Как создать объект в новой куче?
Ответ Создать тему
Опции темы

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