C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
TXMLDocument | Invalid Pointer Operation на выходе
Praetorean
  Отправлено: 22.12.2005, 20:46


Ученик-кочегар

Группа: Участник
Сообщений: 3



Вобщем имеется проект.
В нем присутствует компонент TXMLDocument
я в него загружаю свой xml файл в OnShow формы
...далее различные действия в плане чтения данных из этого объекта...
при любом варианте закрытия программы
(exit(0) Application->Terminate() Close() и просто обычное нажатие на крест) возникает ошибка Invalid Pointer Operation — но это только при отладке в самой среде. если дебаг убрать или прсто руками запустить мой ехе то винда сообщает что в приложении найдена ошибка — репорт в майкрософт, потом месаджбокс "Abnormal program terminated"

Если просто загрузить файл xml но не выполнять никаких действий то выход без ошибки.

но после выполнения вот такой функции:

CODE
void __fastcall TDriveListerForm::BuildTree(TXMLDocument *xmd)
{
IXMLNode *xf=(IXMLNode *)xmd->ChildNodes->First();
IXMLNode *xmultistatus=(IXMLNode *)xf->NextSibling();
_di_IXMLNodeList responses=xmultistatus->ChildNodes;

_di_IXMLNode p,href,restype,r;
_di_IXMLNodeList pl;
int dir=0;
__int64 x1=0;
AnsiString res,user;
map<AnsiString,__int64>::iterator ui;
p=responses->First();
xpb->Max=responses->GetCount();
xpb->Visible=1;
xpb->Position=0;
Application->ProcessMessages();
while (p)
{
pl=p->GetChildNodes();
href=pl->Get(0);
restype=href->NextSibling()->ChildNodes->FindNode("D:prop")->ChildNodes->FindNode("D:resourcetype");
dir=0;
if (restype)
{
res=restype->ChildNodes->First()->GetNodeName();
if (res=="D:collection") dir=1;
}
if (!dir){
               pl=p->GetChildNodes();
               r=pl->FindNode("D:propstat");
               pl=r->GetChildNodes();
               r=pl->FindNode("D:prop");
               pl=r->GetChildNodes();
               r=pl->FindNode("D:getcontentlength");
               x1=r->GetNodeValue().operator __int64();
               drivesize+=x1;

               r=pl->FindNode("modificationuser","");
               if (r) user=AnsiString(r->GetNodeValue()); else user="";

               if (user!="") {

               if ((ui=userupload.find(user))==userupload.end())
                        userupload.insert(pair<AnsiString,__int64>(user,x1));
                        else
                        ui->second+=x1;
                        }
               }
AddNode(href->GetNodeValue(),(void *)(p.operator IXMLNode *()),dir);
p=p->NextSibling();
xpb->Position+=1;
}
}


выход всегда с ошибками вышеуказанными.

что в этом коде неверно?

я вообще изначально чувствовал что чета я не так делаю.
но не знаю что:)


если закоментировать функцию AddNode то опять же ошибки нет на выходе.

но AddNode уже не оперирует с XML....


но там есть добавление в TreeView вот такое

CODE
drive->Items->AddChildObject(parent,path,d);


вот этот d — указатель на соотв. xml-ноду

но может быть я не правильно передаю указатель на нее в эту функцию

я передаю как d — вот это: (void *)(p.operator IXMLNode *())

(см.выше)


где же ошибка?
Admin
Отправлено: 22.12.2005, 20:55


Владимир

Группа: Администратор
Сообщений: 1190



Код не смотрел, но посмотрите, нет ли какого обработчика
события компонента TXMLDocument, если есть — попробуйте
отключить обработчик перед закрытием формы.

То есть в OnClose формы вставьте что-то типа
TXMLDocument->On... = NULL;

Обычно сталкивался с подобным, когда программа при закрытии
пытается выполнить некий обработчик события для какого-либо
объекта.

Отредактировано Admin — 22/12/2005, 20:58
Praetorean
Отправлено: 22.12.2005, 22:07


Ученик-кочегар

Группа: Участник
Сообщений: 3



Врубил полный дебаг и понял что ошибка возникает вот в модуле System.pas
CODE

function _FreeMem(P: Pointer): Integer;
{$IF Defined(DEBUG) and Defined(LINUX)}
var
 Signature: PLongInt;
{$IFEND}
begin
 if P <> nil then
 begin
{$IF Defined(DEBUG) and Defined(LINUX)}
   Signature := PLongInt(LongInt(P) — 4);
   if Signature^ <> 0 then
     Error(reInvalidPtr);
   Signature^ := FreeMemorySignature;
   Result := MemoryManager.Freemem(Pointer(Signature));
{$ELSE}
   Result := MemoryManager.FreeMem(P);
{$IFEND}
   if Result <> 0 then
     Error(reInvalidPtr);
 end
 else
   Result := 0;
end;


В строчке Error(reInvalidPtr);

Отредактировано Praetorean — 22/12/2005, 22:07
Praetorean
Отправлено: 22.12.2005, 22:10


Ученик-кочегар

Группа: Участник
Сообщений: 3



Тоесть как я понимаю ошибка возникает
изза попытки повторной очистки памяти под указателем.

Первый раз все нормально — а во второй раз в указателе все еще содержится тот адрес но память уже очищена.

Вернуться в Вопросы программирования в C++Builder