![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
tinyxml -- Memory Management -- Does It Manage Some Or Is It All You? |
bamccaig
Member #7,536
July 2006
![]() |
OK, so I decided to try to learn some XML related stuff and figured the best place to start would be actually working with documents in a real programming language. I started by downloading tinyxml, tinyxpath, and tinyxml++ source to the computer sciences server at the college and compiled all three. I read through some tinyxml documentation and started following this tutorial. It's not even really so much a tutorial as it is example code in unstructured order. I'm wondering if anybody knows whether the TiXmlDocument is going to manage these children or whether I'm supposed to destroy them after (which seems more likely). I did a little reading through the documentation and checked the source and didn't see anything to suggest that the TiXmlDocument would be managing the memory of children so I wrote a simple macro to check a pointer, delete it, and set it to 0 and started implementing it. However, for some reason one of my pointers is causing a SEGFAULT in (IIRC) build_simple_doc on line 101.
** EDIT ** I added a line just before the 3 DELETE macros where the SEGFAULT occurs and accessed a member of text and it seemingly worked fine: -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
ReyBrujo
Moderator
January 2001
![]() |
I am guessing tinyxml frees the memory of all its children (just like any XML library would do), so you are basically double freeing the pointer. (Edited: Indeed, it loops all the nodes and deletes them all). -- |
bamccaig
Member #7,536
July 2006
![]() |
Ah, I see... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Speedo
Member #9,783
May 2008
|
The segfault is probably not from your macro, but from the document's destructor as it goes out of scope. When you programaticaly build a file with Tinyxml, you have two options for adding new elements: I prefer the latter. It tends to avoid this confusion about "well, do I need to need to free the memory, or not...?". If you're in a situation where you're anal about objects being copied, obviously you may prefer the former method. Personally, I would skip the tutorial (it's not very helpful) and just start working on something yourself. Tinyxml is really very easy to use once you grasp the basics. |
Kitty Cat
Member #2,815
October 2002
![]() |
delete and free will already no-op when given NULL. You don't need to check them. And when doing a block command with a macro, you should use do{}while(0) like: #define MYMACRO() do { \ ..stuff.. \ } while(0) ... MYMACRO(); ..so you won't have any nasty side effects with the semicolon or if/for/while commands. -- |
bamccaig
Member #7,536
July 2006
![]() |
Speedo said: The segfault is probably not from your macro, but from the document's destructor as it goes out of scope. Yeah, I suspected that after ReyBrujo pointed out that the document was in fact destroying it's children. Speedo said: I prefer the latter. It tends to avoid this confusion about "well, do I need to need to free the memory, or not...?". If you're in a situation where you're anal about objects being copied, obviously you may prefer the former method. I like that there is a more clear approach, but I also like the efficiency of using pointers instead of forcing it to copy objects. Plus, you can theoretically reduce the number of variables required by reusing some of the pointers whereas stack objects would need to be declared individually (though I guess if they're copied they could be reused too...). Speedo said: Personally, I would skip the tutorial (it's not very helpful) and just start working on something yourself. Tinyxml is really very easy to use once you grasp the basics. I suspect you're right, but I don't think there's very much left to the tutorial anyway. Might as well see what else they've done. I'll probably be trying to find a tinyxpath tutorial next. Kitty Cat said: delete and free will already no-op when given NULL.
I knew free did, but wasn't sure about delete and wanted to eliminate that as a possibility for causing a crash. Also, it would save the unnecessary assignment. I'm not sure which would be slower between an unnecessary condition and an unnecessary assignment. Kitty Cat said: ..so you won't have any nasty side effects with the semicolon or if/for/while commands.
I don't see the difference (aside from requiring the semi-colon in yours). -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Kitty Cat
Member #2,815
October 2002
![]() |
Quote: I knew free did, but wasn't sure about delete and wanted to eliminate that as a possibility for causing a crash. Also, it would save the unnecessary assignment. I'm not sure which would be slower between an unnecessary condition and an unnecessary assignment. An if statement is more costly than an int/pointer assignment. As long as you always set a pointer to 0/NULL after you free or delete it, you never have to check before you free or delete it. Quote: I don't see the difference (aside from requiring the semi-colon in yours). -- |
Speedo
Member #9,783
May 2008
|
The do { stuff } while (0) approach though will generate less efficient code on some compilers. IIRC a better approach is #define MYMACRO if (1) \ { \ somefunction(); \ someotherfunction(); \ } \ else (void)0 Either way it's just another reason IMO to trash macros whenever possible and use inline functions. Quote: I don't see the difference (aside from requiring the semi-colon in yours). Consider this code with your macro: bool isDone; ... if (isDone) DELETE(somepointer); else cout << "not done!"; The if statement would expand to: if (isDone) { if (somepointer) { delete somepointer; somepointer = 0; } }; // <-- BAD! else cout << "not done!"; That semicolon is going to seperate the if statement from the else... and you'll get compile errors. |
bamccaig
Member #7,536
July 2006
![]() |
Kitty Cat said: An if statement is more costly than an int/pointer assignment.
I suppose that makes sense... Kitty Cat said: As long as you always set a pointer to 0/NULL after you free or delete it, you never have to check before you free or delete it.
Yes, well, as long as you free memory resources after you're done with them there will be no need for garbage collectors, but modern language designers still thought they were useful. Speedo said: Either way it's just another reason IMO to trash macros whenever possible and use inline functions. The problem with an inline function is that I would need to pass a pointer to my pointer to assign it a NULL value, which is less pretty (because of the address-of operator) and more error prone. A macro avoids those subtleties. Speedo said: That semicolon is going to seperate the if statement from the else... and you'll get compile errors.
Ah, I see... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Speedo
Member #9,783
May 2008
|
Quote: The problem with an inline function is that I would need to pass a pointer to my pointer to assign it a NULL value, which is less pretty (because of the address-of operator) and more error prone. A macro avoids those subtleties.
References work with pointers... template<typename T> inline void DELETE(T*& ptr) { delete ptr; ptr = 0; }
|
bamccaig
Member #7,536
July 2006
![]() |
Speedo said:
References work with pointers...
OMG! ** EDIT ** I'm having problems calling it though. I'm getting a linker error: undefined reference to `void bam_delete<TiXmlElement>(TiXmlElement*&)'
Am I calling it wrongly? -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
ReyBrujo
Moderator
January 2001
![]() |
Don't you need to specialize template functions? -- |
bamccaig
Member #7,536
July 2006
![]() |
ReyBrujo said: Don't you need to specialize template functions?
I don't formally know how to use templates... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
ReyBrujo
Moderator
January 2001
![]() |
Then, shouldn't you call it bam_delete(window); directly? -- |
bamccaig
Member #7,536
July 2006
![]() |
ReyBrujo said: Then, shouldn't you call it bam_delete(window); directly?
I get the same result. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Speedo
Member #9,783
May 2008
|
Quote:
I'm getting a linker error: Well, you don't have give the template parameter when you call it (though it shouldn't make a difference if you do). Where did you define the function, how is it included, etc? |
bamccaig
Member #7,536
July 2006
![]() |
That's the ugly part... I'm using a Makefile and I don't really know what I'm doing with them... The implementation is in include/bam and src/bam and everything is compiled with a very manual Makefile because I haven't figured out Makefiles yet. src/bam/bam.hpp: #ifndef BAM_HPP #define BAM_HPP /* bam/bam.h (and bam/bam.c) is the macro implementation... */ #include <bam/bam.h> template<typename T> inline void bam_delete(T *&); template<typename T> inline void bam_free(T *&); #endif src/bam/bam.cpp:
src/main.cpp: #include <bam/bam.hpp> . . . bam_delete(window); Makefile:
** EDIT ** Unless the #include <bam/bam.hpp> should be using double-quotes (""), even though I added a -Iinclude option to g++. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
templates have to be inlined, and that means they have to go in their own headers. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
![]() |
Edgar Reynaldo said: templates have to be inlined, and that means they have to go in their own headers.
-- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
You can't link to a template class across modules - you have to completely define the template class in a header file. It has something to do with instantiation of templated objects. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
![]() |
Edgar Reynaldo said: You can't link to a template class across modules - you have to completely define the template class in a header file. It has something to do with instantiation of templated objects.
I moved the template function definitions into include/bam/bam.hpp and it still doesn't work... -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
Peter Wang
Member #23
April 2000
|
Quote: The do { stuff } while (0) approach though will generate less efficient code on some compilers. Name names? Quote: IIRC a better approach is That's too hard to remember.
|
Edgar Reynaldo
Major Reynaldo
May 2007
![]() |
It may not matter, but did you comment out the declarations, and just leave the definitions? You could try using template <class T> instead of template <typename T>. Don't forget -Wall in your makefile's CPPFLAGS.
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
bamccaig
Member #7,536
July 2006
![]() |
Edgar Reynaldo said: It may not matter, but did you comment out the declarations, and just leave the definitions? I removed the declarations and just left the definitions. Edgar Reynaldo said: You could try using template <class T> instead of template <typename T>. Don't forget -Wall in your makefile's CPPFLAGS. I'll give it a try. Edgar Reynaldo said: It could be old .o files causing it - try cleaning them out and rebuilding it. I touch'd all the include files before make'ing so I assume that should have rebuilt the whole thing. I'll give it a try though. ** EDIT ** No, that was it. Old .o files were getting in the way. -- acc.js | al4anim - Allegro 4 Animation library | Allegro 5 VS/NuGet Guide | Allegro.cc Mockup | Allegro.cc <code> Tag | Allegro 4 Timer Example (w/ Semaphores) | Allegro 5 "Winpkg" (MSVC readme) | Bambot | Blog | C++ STL Container Flowchart | Castopulence Software | Check Return Values | Derail? | Is This A Discussion? Flow Chart | Filesystem Hierarchy Standard | Clean Code Talks - Global State and Singletons | How To Use Header Files | GNU/Linux (Debian, Fedora, Gentoo) | rot (rot13, rot47, rotN) | Streaming |
ReyBrujo
Moderator
January 2001
![]() |
If your makefile doesn't consider headers (for example, file.o : file.cpp file.h as rule) it won't care about the headers. -- |
|
1
2
|