Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.06.2011, 18:26   #1
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию Выделение памяти (new)

Всем привет. Ребят, объясните глупому горекодеру, как логичнее поступить в следующей ситуации:
Код:
typedef struct tagTREENODE
{
	TREEROOT*			pTreeRoot;
	TREECHIELD*			pTreeChield;
} TREENODE, *LPTREENODE;
Выделив память для:
Код:
LPTREENODE pTreeNode = new TREENODE();
Я выделяю память либо для TREEROOT, либо для TREECHIELD, в зависимости от ситуации. Каждая из двух структур состоит из указателей типа WCHAR*. После выделения памяти для одной из двух структур я выделяю память для каждого поля этой структуры так:
Код:
pTreeNode->pTreeRoot->pName = new WCHAR;
Я так понимаю, это - неинициализированная память, да? Просто ссылается на адрес, к примеру 0x012b4d60, размером в 2 байта, верно? Следующее поле может ссылаться на адрес 0x012b4d62? После добавления корня дерева и двух дочерних корней к нему вылетает ошибка, гласящая: "куча была повреждена". Но ошибка не вылетает, если два раза подряд создать два корня дерева, а потом можно что хочешь делать и ошибки не будет. Дело наверное в разности размера двух структур? Избавился от ошибки, явно задав размер каждого поля:
Код:
pTreeNode->pTreeRoot->pName = new WCHAR[90];
Вопрос:Но я не хочу заранее определять размер полей, а только при присвоении им значений. Как это сделать? И ещё, не будет ли рациональнее мне не использовать вот сдесь указатели:
Код:
typedef struct tagTREENODE
{
	TREEROOT			pTreeRoot;
	TREECHIELD			pTreeChield;
} TREENODE, *LPTREENODE;
Может быть память будет экономиться или же скорость работы хоть чуть-чуть... повысится? Мне очень надо максимально оптимизировать средствами си++, но не в дальнейший ущерб удобству разработки...
Добавлено: Сейчас замерил время выполнения добавления элемента с присвоением всех указателей, ровняется 0. GetTickCount использовал. Может быть есть более точный измеритель? Хотя, сейчас в цикле попробую замерить...
Добавлено: Протестировал скорость создания узла без указателей, уменьшилась почти в три раза. Цикл на 10000 раз ставил.
"Тебе то может на меня и насрать, но твои глаза меня обожают!"

Последний раз редактировалось ImmortalAlexSan; 05.06.2011 в 19:05.
ImmortalAlexSan вне форума Ответить с цитированием
Старый 05.06.2011, 19:05   #2
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Цитата:
Просто ссылается на адрес, к примеру 0x012b4d60, размером в 2 байта, верно?
Насколько я помню, в Windows размер любого указателя 4 байта.
_-Re@l-_ вне форума Ответить с цитированием
Старый 05.06.2011, 19:05   #3
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Не читается - это раз, вы так и не объяснили чего хотите - это два, пишется "child" - это три. Если игнорировать контекст и отвечать только на следующий вопрос:
Цитата:
Но я не хочу заранее определять размер полей, а только при присвоении им значений. Как это сделать?
то ответ: RTTI. Но кажется мне, что в вашем случае можно обойтись другими средствами. Обращайтесь в скайп, разберемся в вашей ситуации.

Цитата:
Насколько я помню, в Windows размер любого указателя 4 байта.
Это зависит от разрядности системы. При х32 будет 4 байта, при х64 - уже 8 байт.
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 05.06.2011, 19:11   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

в 32-ых битке 4 байта указатель
а в 64-ох битной вообще 8 байт.
Код:
pTreeNode->pTreeRoot->pName = new WCHAR;
а где инициализация указателей pTreeChield; pTreeRoot;?

структуру содержающую один член вообще считаю что нерационально создавать.

Цитата:
Но я не хочу заранее определять размер полей, а только при присвоении им значений. Как это сделать?
массивы не проходили?
есть еще std::vector, std::list

да и в конце концов
Код:
typedef struct
{
    int length;
    int* data;
}  IntArray;
хотя строки вообще с нультерминалом хранят обычно.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 05.06.2011 в 19:15.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.06.2011, 19:18   #5
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

Код:
typedef struct tagTREEROOT
{
Указатель на WCHAR1
...
...
Указатель на WCHARn
} TREEROOT, *LPTREEROOT;

typedef struct tagTREECHIELD
{
Указатель на WCHAR1
...
...
Указатель на WCHARn
} TREECHIELD, *LPTREECHIELD;

typedef struct tagTREENODE
{
	LPTREEROOT			pTreeRoot;
	LPTREECHIELD			pTreeChield;
} TREENODE, *LPTREENODE;
Вот такая схема получается.
Я хотел узнать как избавиться от ошибки... Которую, я описал выше.
И хотел поинтересоваться в плюсах и минусах использования указателей в данном случае. Я так понимаю, что при динамическом выделении памяти падает скорость вычислений и на программиста вешаются все проблемы, связанные с памятью. А при статическом выделении растет скорость вычислений, нагрузка меньше, но теряется контроль над размерностью областей. Золотой середины, я так понимаю нет?
Пепел Феникса, я не хочу использовать std. Можете привести пример с инициализацией?
"Тебе то может на меня и насрать, но твои глаза меня обожают!"

Последний раз редактировалось ImmortalAlexSan; 05.06.2011 в 19:23.
ImmortalAlexSan вне форума Ответить с цитированием
Старый 05.06.2011, 19:19   #6
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Цитата:
Золотой середины, я так понимаю нет?
Умные (автоматические) указатели, например.
А код у вас, знаете ли, кривой.
Ищете информацию по C++?
cplusplus.com

Последний раз редактировалось Сtrl; 05.06.2011 в 19:21.
Сtrl вне форума Ответить с цитированием
Старый 05.06.2011, 19:25   #7
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

Сtrl, в чем кривость?
"Тебе то может на меня и насрать, но твои глаза меня обожают!"
ImmortalAlexSan вне форума Ответить с цитированием
Старый 05.06.2011, 19:31   #8
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Я так понимаю, что при динамическом выделении памяти падает скорость вычислений и на программиста вешаются все проблемы, связанные с памятью.
интересно а в честь чего падает то скорость? или вы собираетесь в цикле выделять по байту?
Цитата:
я не хочу использовать std.
почему же?
Цитата:
Можете привести пример с инициализацией?
любой указатель нужно инициализировать до примениния, у вас надо создать внутренние структуры(на которые у вас указатель)
Цитата:
Избавился от ошибки, явно задав размер каждого поля:
а это явно можно и от переменной указывать.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 05.06.2011, 19:32   #9
Сtrl
C++
Форумчанин
 
Аватар для Сtrl
 
Регистрация: 27.03.2011
Сообщений: 803
По умолчанию

Цитата:
Сообщение от ImmortalAlexSan Посмотреть сообщение
Сtrl, в чем кривость?
Самое бросающееся в глаза - это форматирование. Далее - дерево делается с использованием двух классов - элемент и внешняя обертка. Итератор - это отдельный разговор. Ну и с typedef вы намудрили, конечно.
Ищете информацию по C++?
cplusplus.com
Сtrl вне форума Ответить с цитированием
Старый 05.06.2011, 19:41   #10
netrino
Участник клуба
 
Аватар для netrino
 
Регистрация: 15.07.2008
Сообщений: 1,933
По умолчанию

Код:
LPTREENODE pTreeNode = new TREENODE;
pTreeNode->pTreeRoot = new TREEROOT;
pTreeNode->pTreeChild = new TREECHILD;
size_t NameLength = GetNameLength();
pTreeNode->pTreeRoot->pName = new WCHAR[NameLength]; // Неконстантная длина имени
...
Это судя по всему тому, что вы сказали. Но всё, может поделитесь тем, что это такое, быть может есть более простой способ? А форматирование хорошее у вас.
netrino вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выделение памяти в С++ Dj-IIyIIc Общие вопросы C/C++ 4 18.10.2010 14:39
выделение памяти Артем1256 Общие вопросы C/C++ 1 13.11.2009 16:38
Выделение памяти mutabor Общие вопросы Delphi 8 26.08.2009 18:16
До выделение памяти MAKTE Общие вопросы C/C++ 4 20.05.2008 21:34
Выделение памяти antoha.by Паскаль, Turbo Pascal, PascalABC.NET 2 29.04.2008 20:04