查看单个帖子
旧 2009-05-04, 06:26 PM   #1
yang686526
高级会员
 
注册日期: 06-11
帖子: 14579
精华: 1
现金: 224494 标准币
资产: 234494 标准币
yang686526 向着好的方向发展
默认 【转帖】crash in 1.14.02 when append entities to newly created datab

crash in 1.14.02 when append entities to newly created datab
crash in 1.14.02 when append entities to newly created database
i'm trying to create a dwg file and add entities to the paper space table. here's the code (relevant portions only):
oddbdatabaseptr m_pfile = m_appservices.createdatabase(true);
m_pblocks = m_pfile->getblocktableid().safeopenobject();
m_pblockiter = m_pblocks->newiterator();
m_pblockiter->start();
m_pblock = m_pblockiter->getrecordid().safeopenobject();
m_pentiter = m_pblock->newiterator();
... later on, it does this
try {
oddb3dpolyline line;
...fill out line ...
m_pblock->appendoddbentity(&line); //throws an exception
}
catch (oderror& error) {
// ******crashes on next line ************
odstring str = error.description();
}
here's the crash stack trace:
dwgd.dll!oderrorcontext::completedescription() line 120 + 0x9
dwgd.dll!oderror::description() line 92 + 0xf
block is not open for write?
vladimir
ok, i'm now passing the two calls to safeopenobject oddb::kforwrite. now when i try to append the polyline, it crashes before my debug assert function gets called.
here's the stack trace:
dwgd.dll!oddbdatabaseimpl::getimpl() line 137 + 0x6
dwgd.dll!oddbobject::assertwriteenabled() line 67 + 0x9
dwgd.dll!oddbobject::setownerid() line 1591
dwgd.dll!odentitycontainer::makedbrolist() line 83 + 0x11
dwgd.dll!odentityseqendcontainer::makedbrolist() line 732
dwgd.dll!oddbdatabase::addoddbobject() line 926 + 0xd
dwgd.dll!odentitycontainer::appendentity() line 560 + 0x20
dwgd.dll!oddbblocktablerecordimpl::appendentity() line 1822 + 0x10
dwgd.dll!odentitycontainer::append() line 500 + 0x15
dwgd.dll!oddbblocktablerecord::appendoddbentity() line 284
purify reports the following free memory read:
error location
oddbobjectimpl::isreadenabled(void)const [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \objects\dbobjectimpl.h:131]
oddbobject::isreadenabled(void)const [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \objects\dbobject.cpp:105]
oddbobject::assertreadenabled(void)const [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \objects\dbobject.cpp:397]
oddbobject:bjectid(void)const [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \objects\dbobject.cpp:162]
odentitycontainer::makedbrolist(void) [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \entities\entitycontainer.cpp:74]
odentityseqendcontainer::makedbrolist(void) [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \entities\entitycontainer.cpp:731]
oddbdatabase::addoddbobject(oddbobject *,oddbobjectid,oddbhandle) [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \dbdatabase1.cpp:926]
odentitycontainer::appendentity(oddbentity *) [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \entities\entitycontainer.cpp:560]
oddbblocktablerecordimpl::appendentity(oddbentity *) [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \tables\dbblocktablerecord.cpp:1822]
odentitycontainer::append(oddbentity *) [d:\opendwg\dd1.14\dwgdirect_vc2003\source\database \entities\entitycontainer.cpp:500]
this is followed by an exception being handled in oddbobject::assertreadenabled, after which there are writes to and deletes of invalid memory in oddbobject::release when called by destructors. can post more details of the log if it would be helpful.
code:
oddb3dpolyline line;
...fill out line ...
m_pblock->appendoddbentity(&line); //throws an exception
this is suspicious. looks like you are trying to add temporary object to database.
correct way should look like:
code:
oddb3dpolylineptr line = oddb3dpolyline::createobject();
...
m_pblock->appendoddbentity(line);
vladimir
you were right, that was the problem.
now i have another problem. the database appears to be created successfully and all elements appended without problems. however, when i call writefile an exception gets thrown with the error message "was open for write object: (1f)".
here's my code:
code:
odstreambufptr pfile = s_sysservices.createfile(fnamestr, oda::kfilewrite);
oddb::savetype savetype = type == filetype_dwg ? oddb::kdwg : oddb::kdxf;
m_file->writefile(pfile, savetype, oddb::vac18); //autocad 18
this code does create an output file of 1472 bytes which is apparently not a valid dwg. m_file is an oddbdatabaseptr.
it literally means that object with handle 1f was not closed when write operation occured.
perhaps you did not release some smartpointer.
vladimir
after releasing all od smart pointers in my class, and then writing, it works.
thanks for your help vladimir.

is what broncofan made compulsory? must all smart pointers be released before writing the file? i thought releasing oddbdatabaseptr foodb would have been enough.
by the way, what is the exact difference between foodb.release() and foodb->release()? i am aware of the differences between oddbdatabase variables and their smart pointer associated, yet i cannot figure out how a database *not its reference* can be released. the documentation didn't help me to clarify. perhaps you made this as a trick? i know from past threads that cases happened when one tried to release the variable, not its reference.
thanks for clarifying.
mirko.
releasing database does not close all the objects automatically. the easy way to handle smart-pointers is to put them in {} scope. in that case they will be destroyed when you leave scope.
quote:
what is the exact difference between foodb.release() and foodb->release()?
assuming that foodb is oddbdatabaseptr, foodb.release() releases smart pointer and decrement database reference count. foodb->release() does just the latter. that is - the second action is dangerous and may lead to crash. addref/release reference counting is completely hidden by smart-pointer mechanics, and you should not use it when it is not necessary.
if you need to release smart pointer manually, you should better assign zero to it. foodb = 0 is equivalent to foodb.release(), but is more readable and clear.
vladimir

thanks for your explanations, vlad. i already use foodb = 0... that was just a curiosity. for what concerns scoping, i already apply that concept too... only didn't figured out that, out of scope, not only is the foodb released, but most likely any variable related to it, provided it was created in the same scope!
it's wonderful how funny a library can be!
yang686526离线中   回复时引用此帖
GDT自动化论坛(仅游客可见)