powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / access violetion при приведении node->data к типу структуры
13 сообщений из 13, страница 1 из 1
access violetion при приведении node->data к типу структуры
    #32935665
Евгений, Екатеринбург
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот структура

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
typedef struct TypeID
{
int ID;
int ParID;
int Type;
int ParType;
int DType;
int ParDType;
} TTypeID;
typedef TTypeID* PTypeID;

Вот код где иногда, примерно один раз из 50 возникает ошибка

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
void __fastcall TMainform::TreeView1Expanding(TObject *Sender,
      TTreeNode *Node, bool &AllowExpansion)
{
Node->DeleteChildren();
TypeID *NodeData=NULL;
NodeData=PTypeID(Node->Data);//вот здесь показывает ошибку
//access violetion in module "vcl60.bpl"
int ID;
ID=NodeData->ID;
int ParID;
ParID=NodeData->ParID;
int type;
type=NodeData->Type;
int dtype;
dtype=NodeData->DType;
int selected;
selected=TreeView1->Selected->AbsoluteIndex;
if (Node->ImageIndex== 3 )
{
Node->ImageIndex= 6 ;
Node->SelectedIndex= 8 ;
}
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32935674
Cast3
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мб трётся память кем-то другим, и не здесь.
Чекать всякими там BoundsChecker'ами -- единственное, что могу посоветовать. Потому что здесь ИМХО всё правильно и даже не вызывает подозрений.
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32935680
Фотография JibSkeart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
if Node->Data != NULL

Хммм , наверное это забыли ?



 ш
(';')
(V),(V),,
Код: plaintext
 JS 
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32935797
Евгений, Екатеринбург
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JibSkeartif Node->Data != NULL

Хммм , наверное это забыли ?



Да, надо будет поставить такое условие, хотя в моем случае этого нигде не должно быть, ибо со всеми узлами дерева связана такая структура и в большинстве случае это работает. Но если происходит такой сбой, то все, капец, только перезапуск проги помогает, начинает на всех узлах выскакивать...


Подскажите еще пожалуйста - а почему такое исключение не перехватывается блоком
Код: plaintext
try {} catch (....) {}

Cast3 Мб трётся память кем-то другим, и не здесь.
Чекать всякими там BoundsChecker'ами -- единственное, что могу посоветовать. Потому что здесь ИМХО всё правильно и даже не вызывает подозрений.

А как это делать, что это такое?
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32937549
archez
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А вот интересно, в каком месте выделяется память для структуры и в каком она освобождается?
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32937641
Евгений, Екатеринбург
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
archezА вот интересно, в каком месте выделяется память для структуры и в каком она освобождается?

:-) вот кусок побольше, дальше примерно то же самое... освобождается на событие delete каждой ноды.


Код: plaintext
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.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
void __fastcall TMainform::TreeView1Expanding(TObject *Sender,
      TTreeNode *Node, bool &AllowExpansion)
{
Node->DeleteChildren();
TypeID *NodeData=NULL;
NodeData=PTypeID(Node->Data);
int ID;
ID=NodeData->ID;
int ParID;
ParID=NodeData->ParID;
int type;
type=NodeData->Type;
int dtype;
dtype=NodeData->DType;
int selected;
selected=TreeView1->Selected->AbsoluteIndex;
if (Node->ImageIndex== 3 )
{
Node->ImageIndex= 6 ;
Node->SelectedIndex= 8 ;
}
//------------------------------------
if (type ==  1 )
{
IBQuery1->SQL->Clear();
IBQuery1->SQL->Add("select * from selrazdel (:PO_ID)");
IBQuery1->ParamByName("PO_ID")->AsInteger=ID;
IBQuery1->Active=true;
IBQuery1->First();
TypeID *raz;
TTreeNode *NewRaz;
while (!IBQuery1->Eof)
{
NewRaz=TreeView1->Items->AddChild(Node, IBQuery1->FieldByName("prr_name")->AsString);
raz = new (TypeID);
raz->ID=IBQuery1->FieldByName("prr_ID")->AsInteger;
raz->ParID=ID;
raz->Type= 2 ;
raz->ParType=type;
NewRaz->Data=raz;
if (IBQuery1->FieldByName("prr_Count")->AsInteger> 0 )
{
NewRaz->HasChildren=true;
NewRaz->ImageIndex= 3 ;
NewRaz->SelectedIndex= 5 ;
NewRaz->StateIndex= 3 ;
}
else
{
NewRaz->HasChildren=false;
NewRaz->ImageIndex= 4 ;
NewRaz->SelectedIndex= 4 ;
NewRaz->StateIndex= 4 ;
}
IBQuery1->Next();
}
}
//----------------------------
if (type ==  2 )
{
IBQuery1->SQL->Clear();
IBQuery1->SQL->Add("select * from selelem (:PRR_ID)");
IBQuery1->ParamByName("PRR_ID")->AsInteger=ID;
IBQuery1->Active=true;
IBQuery1->First();
TypeID *elem;
TTreeNode *NewElem;
while (!IBQuery1->Eof)
{
NewElem=TreeView1->Items->AddChild(Node, IBQuery1->FieldByName("pE_name")->AsString);
elem = new (TypeID);
elem->ID=IBQuery1->FieldByName("pE_ID")->AsInteger;
elem->ParID=ID;
elem->Type= 3 ;
elem->ParType=type;
NewElem->Data=elem;
if (IBQuery1->FieldByName("pE_Count")->AsInteger> 0 )
{
NewElem->HasChildren=true;
NewElem->ImageIndex= 3 ;
NewElem->SelectedIndex= 5 ;
NewElem->StateIndex= 5 ;
}
else
{
NewElem->HasChildren=false;
NewElem->ImageIndex= 4 ;
NewElem->SelectedIndex= 4 ;
NewElem->StateIndex= 6 ;
}
IBQuery1->Next();
}
}

авторif Node->Data != NULL

Хммм , наверное это забыли ?

попробовал
Код: plaintext
if (Node->Data != NULL)//один раз именно тут ошибку выдал (теперь все вообще запуталось, но вроде реже стало появляться сообщение об ошибке)..
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32938381
Фотография JibSkeart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а что делается в функции PTypeID ?


 ш
(';')
(V),(V),,
Код: plaintext
 JS 
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32938557
Евгений, Екатеринбург
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JibSkeartа что делается в функции PTypeID ?


Это не функция....
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
typedef struct TypeID
{
int ID;
int ParID;
int Type;
int ParType;
int DType;
int ParDType;
} TTypeID;
typedef TTypeID* PTypeID;

Я не силен в C++, но по-моему это указатель на структуру типа TTypeID. Я взял это из встроенной справки и немного переделал под свои нужды.
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32940012
archez
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если я правильно понимаю, - у тебя код выделяющий память висит на OnExpanding. Т.е. каждый раз когда пользователь разворачивает ветку происходит удаление всего что ниже этого узла и новое выделение памяти для подструктуры?

Я бы предложил другое решение: инициализировать всю структуру разом по OnCreate. Если необходимо динамическое изменение структуры, то либо переинициализировать всю структуру заново (предварительно удалив ее и освободив память) по событию, в случае если структура большая и ее создание отнимает много времени, отслеживать добавление/удаление каждого элемента и выделять/освобождать память именно для него, а не для всей ветки.

Непонятны такие моменты:
1 Выделяется ли память для элементов корневого уровня. Потому что при OnExpanding предполагается что память для Node->Data уже выделена. Иначе ты пытаешься записать что-то туда куда нельзя.

2 Освобождается ли память, для элементов подструктуры. Т.е. если OnExpanding происходит для 1-го уровня, то освободится ли память для 2-го, 3-го и ниже уровней, если нет - то утечка памяти.

3 И еще, я не уверен в корректности этого кода:
TypeID *raz;
...
while (...)
{
...
raz = new (TypeID);
...
NewRaz->Data=raz;
...
}
Освобождает память наверно что-то вроде:
delete NewRaz->Data;

Я бы попробывал так:
NewRaz->Data=new (TypeID);

4 Из личного опыта - когда код срабатывает 50 раз, а на 51 вылетает, то почти всегда это утечка памяти. Ищи где ты забыл освободить память.

Удачи!
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32940023
kuzzi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
void __fastcall TMainform::TreeView1Expanding(TObject *Sender,
TTreeNode *Node, bool &AllowExpansion)
{
Node->DeleteChildren();
// убедитесь, что ранее выполняется
// Node->Data = reinterpret_cast<void*>(TypeIDStruct);
TypeID* NodeData = reinterpret_cast<PTypeID>(Node->Data);
if (NodeData == 0)
{
throw Exception("Go to debugger ;)");
}
// ну и инициализация в одной строчке с объявлением как-то красивее
int ID = NodeData->ID;
int ParID = NodeData->ParID;
int type = NodeData->Type;
int dtype = NodeData->DType;
int selected = TreeView1->Selected->AbsoluteIndex;
if (Node->ImageIndex==3)
{
Node->ImageIndex=6;
Node->SelectedIndex=8;
}

... и прочитайте для начала Страуструпа
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32940100
Евгений, Екатеринбург
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
archez

Непонятны такие моменты:
1 Выделяется ли память для элементов корневого уровня. Потому что при OnExpanding предполагается что память для Node->Data уже выделена. Иначе ты пытаешься записать что-то туда куда нельзя.

2 Освобождается ли память, для элементов подструктуры. Т.е. если OnExpanding происходит для 1-го уровня, то освободится ли память для 2-го, 3-го и ниже уровней, если нет - то утечка памяти.

3 И еще, я не уверен в корректности этого кода:
TypeID *raz;
...
while (...)
{
...
raz = new (TypeID);
...
NewRaz->Data=raz;
...
}
Освобождает память наверно что-то вроде:
delete NewRaz->Data;

Я бы попробывал так:
NewRaz->Data=new (TypeID);

4 Из личного опыта - когда код срабатывает 50 раз, а на 51 вылетает, то почти всегда это утечка памяти. Ищи где ты забыл освободить память.

Удачи!

Спасибо.
1. Для корневых узлов делается то же самое только на OnCreate формы, они не меняются...
2. Да, память освобождается, удалются дети, значит удаляются и все внуки а на ondelete висит именно delete NewRaz->Data
3. Попробую хотя и не понял чем отличается.
4. Это верно, в первом варианте программы память я не освобождал вообще и ошибка появлялась гораздо чаще.
Я предполагал что если память не освобождать, то просто будут заниматься лишние байты и все, структура-то не большая.
Искать долго придется так как есть еще подобное OnChange и еще несколько компонентов где использется такой метод.

авторNode->DeleteChildren();
Код: plaintext
1.
2.
// убедитесь, что ранее выполняется
// Node->Data = reinterpret_cast<void*>(TypeIDStruct);
TypeID* NodeData = reinterpret_cast<PTypeID>(Node->Data);


А почему оно должно ранее выполняться я ведь не детей привожу к типу, а элемент, ведь сам элемент не удаляется...
чем
Код: plaintext
TypeID* NodeData = reinterpret_cast<PTypeID>(Node->Data);
отличается от
Код: plaintext
1.
TypeID *NodeData=NULL;
NodeData=PTypeID(Node->Data);

Спасибо всем, теперь направление поиска вроде понятно:
1. книжный магазин :-)
2. неосвобожденная память....

зы. Подскажите, если в этом обработчике обявлено столько переменных их надо в конце обработкичика освобождать например delete ID или они сами освободяться когда обработчик отработал. Вроде я читал что переменные обявленные внутри блока автоматически убиваются при выходе из блока....
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32940112
Фотография JibSkeart
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сам создал , сам удаляй :)

но это не для всех случаев ,
если вы делаете так

TMyComp * mycomp = new TMyComp(this);
то уничтожать не надо за это сделает владелец ,
а если так

TMyComp * mycomp = new TMyComp(nil);

то нужно

delete mycomp;

ну это к приминению компонент так скажем .

а в остальных случаях создал удали .


 ш
(';')
(V),(V),,
Код: plaintext
 JS 
...
Рейтинг: 0 / 0
access violetion при приведении node->data к типу структуры
    #32942613
archez
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Евгений, Екатеринбург[quot archez]
зы. Подскажите, если в этом обработчике обявлено столько переменных их надо в конце обработкичика освобождать например delete ID или они сами освободяться когда обработчик отработал. Вроде я читал что переменные обявленные внутри блока автоматически убиваются при выходе из блока....

Если ты просто объявляешь переменную, "int ID" - то ее удалять не нужно, более, того "delete ID" в данном случае приведет к ошибке. Насколько я помню, располагаются такие переменные в основной памяти и выделением/освобождением занимается сама программа. Переменные которые которые объявляются с использованием "new" располагаются в "куче" (читай выше JibSkeart). Однако нужно понимать, что при объявлении типа:

TypeID *raz = new (TypeID);

Сам указатель "ras" будет располагаться в основной памяти, а структура типа "TypeID" на которую ссылается этот указатель - в куче. Я не встречал в литературе такого приема:

raz = new (TypeID);
...
NewRaz->Data=raz;

поэтому не уверен, что в этом случае указателю NewRaz->Data передаются, так сказать, права на эту память. Соответственно я не уверен, что она корректно освобождается при "delete NewRaz->Data". Существует класс SmartPointer, который позволяет выделять память под объекты и не переживать за ее освобождение.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / access violetion при приведении node->data к типу структуры
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]