Is std::list<> not good enough?
Is std::list<> not good enough?
Swoopy, I tried your suggestion, but it doesn't seem to work, when I start up a program to try to steal back some memory it has no effect, (or simply begins to write to my page file when it has consumed all of my system's memory)... I am doubting it is any issue with windows, because it releases all of the memory upon exit, it is how I deleting nodes that is the problem... I am not doing something right.
Lol. Yes, I know... but sometimes since I have lines stretching across the screen and it helps to break them up with paranthesis, and I just end up using it throughout the program.Originally Posted by iMalc
I don't see what you mean. The list begins at NodeStart, and ends on NodeEnd, I have Forward and Backward links throughout the list for navigation. And, I am deleting nodes the same way I have seen in *every single* LL tutorial/reference I have ever seen, using free()/delete.Originally Posted by iMalc
As for comments, I figured the operation was pretty straight forward here... if you can't understand my deletion function without comments, you can't help me. Simple as that.
Better function names... *laughs* what would you suggest? Those are pretty easy buddy.Originally Posted by iMalc
NodeRecent does serve a purpose, just the functions that use it are not present in the code posted.Originally Posted by iMalc
Thanks, I'll be sure to keep that out from now on.Originally Posted by iMalc
Nope. I need a little more flexibilityOriginally Posted by UMR_Student
Last edited by josephjah; 07-21-2007 at 07:55 PM. Reason: Typo
Yeah... That's what's puzzling me, I don't see anything else I could release.Originally Posted by vart
It seems that I am leaving something behind in each node that is roughly 10-15% of the size of the node, and when I perform a second cycle the memory is still unusable since it is still taken up.
Right, you don't see what I mean at all. What I mean is that none of your pointers or counters are being set to NULL or zero before adding items to the list. That means that they would begin with a random address. Okay your real program more likely has them initialised, but we can't tell that from a mocked-up code snippet. You need to do your best to make sure that what you post is what you have actually been running. Setting the NodeCount back to zero afterwards is also important because otherwise you can't reuse the list properly.I understand your deletion just fine. That much is very straight forward. The problem is with CreateNode and CreateNodes. Again I know this isn't the real program, but if it were, the function name and signature say nothing about where those nodes go (what points to them), nor does it say in what order they are linked. a name like push_back tells you that the node goes on the back end of the list; CreateNode does not. It is also obvious what list it goes into because push_back is a member function. Yes your other names aren't really that bad, once you correct your spelling of destruct.
As for comments, I figured the operation was pretty straight forward here... if you can't understand my deletion function without comments, you can't help me. Simple as that.
Better function names... *laughs* what would you suggest? Those are pretty easy buddy.I figured as much, but when posting a snippet that reproduces a problem it is best to trim out as much irrelevant stuff as possible. Not just for our benefit, but because it may also help you to more clearly see the problem.
NodeRecent does serve a purpose, just the functions that use it are not present in the code posted.Really?! I'm intriegued as to how any home-baked list could be more flexible that a std::list! Care to elaborate?
Nope. I need a little more flexibility
Last edited by iMalc; 07-21-2007 at 09:56 PM.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
Alright, I see. No, my original code didn't initialize them either, I didn't really have any reason for them to begin in a certain memory location. As long as I am keeping the value of NodeStart and NodeEnd preserved things should be ok right? Or should I still initialize them. And yeah, I fixed the NodeCount reset error, just a careless mistake.Originally Posted by iMalc
de·con·struct(dkn-strkt)Originally Posted by iMalc
tr.v. de·con·struct·ed, de·con·struct·ing, de·con·structs
1. To break down into components; dismantle.
It isn't a spelling error, just used a different word at the time, and it stuck.
*sighs* Sorry.. After eliminating several hundred lines of unrelated code, variables, and definitions, I left a stray var. Oh well.Originally Posted by iMalc
Well, I am using my LL code to attach different types of objects to each node which may themselves contain anything from strings to longs, to links to entirely different sublists.Originally Posted by iMalc
I guess I could probably use it by just storing pointers to each newly created object in the list and then referencing them that way... But I would rather have this worked out because now I am curious... but it seems no one knows why it is behaving in such a strange way..
Ok, I wrote up a simple little program to use std::list but it shares the *exact* same problem as my code, except this takes up more memory, and doesn't create the nodes as fast... I am totally at a loss here.
iMalc, I'll try to stay away from using unconventional words in my function names, it is probably not a good idea.
This code eats up around 670MB vs. my 434MB... and creates the nodes slightly slower, however the .clear() function "works" faster than my hombrew function, but at least mine releases 85% percent of the memory instead of 0%.Code:#include "stdafx.h" #include <iostream> #include <list> using namespace std; struct Node { string handle; }; list <Node*> LIST; void PushBackNode() { LIST.push_back(new Node); } void PushBackNodes(unsigned long n) { for(n;n>0;n--) { PushBackNode(); } } int main() { cout << "Creating nodes..." << endl; PushBackNodes(5); cout << " - " << endl; getchar(); cout << "clearing nodes..." << endl; LIST.clear(); cout << " - " << endl; getchar(); return 0; }
btw, the 'string handle' is just for comparing sizes, I did the same to my previous code which it where I'm getting my numbers.
Last edited by josephjah; 07-21-2007 at 11:10 PM. Reason: Added a thing or two...
Code:list <Node> LIST;
robwhit, I'm not sure that I understand the reasoning behind that.
What I'm thinking, If I use:
andCode:list <Node*> LIST;
I will be creating a new object and then storing a pointer to it... however, now that I am experimenting with std:list I've realized I don't know how to access a particular element without writing a function specifically for that purpose which takes the size of the object and any padding and skips through memory manually....Code:LIST.push_back(new Node);
Any way I can access an element located within the list? sort of like an array or vector?
Yeah you really do have to make sure that they are initialised to NULL at some point. How you do that depends on the real code of yours though. If they're member variables, use a constructor initializer list. If gobals, assign NULL in the declaration. I was once told strictly to always initialise my variables, even though I was using a language and compiler that always did that. It's advice you come to share after a while.Oh of course, that is a real word, I almost forgot. Still in the context of C++ code it is fingernails on a blackboard for many people. Much safer to stick with 'destruct' all the time.
de·con·struct(dkn-strkt)
tr.v. de·con·struct·ed, de·con·struct·ing, de·con·structs
1. To break down into components; dismantle.
It isn't a spelling error, just used a different word at the time, and it stuck.Sorry, didn't mean to be hard on you. Some of us just like to be thorough.*sighs* Sorry.. After eliminating several hundred lines of unrelated code, variables, and definitions, I left a stray var. Oh well.You can use a std::list in two ways.Well, I am using my LL code to attach different types of objects to each node which may themselves contain anything from strings to longs, to links to entirely different sublists.
I guess I could probably use it by just storing pointers to each newly created object in the list and then referencing them that way... But I would rather have this worked out because now I am curious... but it seems no one knows why it is behaving in such a strange way..
Each node contains a pointer to your struct and a pointer to the next/prev nodes, or
Each node is essentially a structure that contains your struct as one of the members and the next/prev pointers as other members.
The later means that the memory allocation/deallocation is handled entirely with/by the list itself. The former means you allocate what the node points to and you delete it later.
Usually you would use the second method and store the object directly in the list. E.g. std::list<string> for a list of strings.
But if the list doesn't own the object (maybe this is just a sublist and they ALL appear in a different list anyway), then you use std::list<string*>
Still it's a good experience to write your own list, so I'd suggest keeping at it until it is sorted anyway. Well done sticking at it so far.
Last edited by iMalc; 07-23-2007 at 12:17 AM. Reason: Sorry, wrote first where I meant second
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
iMalc, Thanks. I've been fiddling with std::list for a little while now and things still aren't working. However I have found the root of my original problem. (Well, sorta)
Currently my main dev computer is running Vista, and so I tried the code on two other computers running XP, and it turns out they are releasing the memory perfectly, there is no leak in XP... So, I have decided to just put up with it and do my hardcore memory-intensive testing on my XP machine.
So, thanks everyone for your help. I only wish there was another solution to the problem.