Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Oct 23rd, 2006, 5:17 PM   #1
Eric the Red
Hobbyist Programmer
 
Eric the Red's Avatar
 
Join Date: Feb 2006
Posts: 214
Rep Power: 0 Eric the Red is an unknown quantity at this point
Heap vs. Stack memory

A while back, we had this discussion already. Found here

However, recently after reading through "Sam's c++ in 24 hours" by Jesse Liberty. I came up across this line: in a section on "arrays of pointers":
Quote:
The arrays discussed so far store all their members on the stack. Usually stack memory is severely limited, whereas heap memory is far larger. It is possible to declare each object on the heap and then to store only a pointer to the object in the array. This dramatically reduces the amount of stack memory used.
Later on in the paragraph right before the example "storing an array on the heap" it states:
Quote:

As an indication of the greater memory that this makes possible, the array is expanded from 5 to 500...
(Obviously an exaggeration "5 to 500")

I bolded the points that were a contrast to what you guys were saying.
Now saying that "Usually stack memory is severely limited, isn't BS is it?" For, many people have not mentioned that.

I'm completely confused now, you guys are saying one thing... the books telling me another thing. What's really going on and why has this author gotten away with being able to write (on the back of the book cover) "Over 250,000 readers have learned c++ from author Jesse Liberty".


/-------------------------------------------------

As Grumpy stated "is only",
Quote:
The distinction between the two forms, from a pure C++ perspective, is only to do with how lifetime of objects are managed.
Again Grumpy,

Quote:
From a C++ language perspective, the only purpose of new and delete are to manage dynamic memory. Nothing more, nothing less.
Dawei

Quote:
It has nothing, really, to do with memory architecture and what areas of memory are more "readily" available than others. The "stack" is, in reality, a lifo stack. Items are stored and retrieved in the expected way for lifo stacks.
Now, how is it that my book tends to go in a completely different direction of what you guys are saying. Now, I know there may be a good explanation for this. Please, someone clear this up.
__________________
Death smiles at us all. All a man can do is smile back.
Eric the Red is offline   Reply With Quote
Old Oct 23rd, 2006, 7:16 PM   #2
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Quote:
Usually stack memory is severely limited, whereas heap memory is far larger.
Simply because this statement is not unequivocally true. Back in the days when the stack was severely limited, the heap was generally severely limited (or nonexistent), too. Given a system with a certain amount of memory, one can generally alter the amounts of memory dedicated to each of these from certain default values.

Now, in the world of multiple processes, each user (let's say they're all C/C++ programs) gets so much memory for global/static data, so much for code, and so much for stack (presuming the really common implementation that actually uses stack, and frequently the processor's call stack). The heap is an area common to all and belonging to none until memory is borrowed, by one of the processes, using malloc or new or kin. You are expected to return this borrowed memory. Generally speaking, returning the memory with delete or free doesn't actually put the memory back on the common heap. It's free for use by the process that originally borrowed it. It is returned to the heap when the program exits or when the program overtly returns it to the heap.

Once again, you must distinguish between how an implementation chooses to work with the language, and what the language expresses as requirements. It would be stupid for the language to try to specify what kind of keyboard or drive or display you have. It would be stupid for your keyboard or display to specify what language you must use. You must have intermediaries that marry the two. That's called platform dependency.

Many, many machines still use a processor-controlled stack, often the call stack, to manage local variables, argument passing, and so forth. It's just a fairly simple way to accomplish the task. These machines mostly DO have registers in addition. I don't know of a commercially viable one that doesn't, in fact. I have only used one uP that didn't implement a call stack. That was an old one, and a piece of crap. Many of the earlier non-micro processors did not implement such a beast. Call tracing and parameter passing were the job of the programmer.

I have at least one post on the forum that describes call-stack operation. It is generalized but fairly detailed, as usage varies somewhat from processor to processor and language implementation to language implementation. See here.

Incidentally, if you look into your compiler documentation, you can PROBABLY find a way to increase your stack space and heap space.

Today's typical desktop machine (large numbers, but definitely in the minority when it comes to all computers) often have grossly huge amounts of memory. The term 'severely limited', in reference to such machines, should not be used by a knowledgeable, modern author. Of course, I also take the position that "Learn ________ in 24 hours (or days, or weeks)" is a flagrantly stupid and misleading statement. It's the ploy of a used-car salesman or a politician or some other brand of thief, cheat, liar, or crook.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Oct 23rd, 2006, 8:37 PM   #3
Eric the Red
Hobbyist Programmer
 
Eric the Red's Avatar
 
Join Date: Feb 2006
Posts: 214
Rep Power: 0 Eric the Red is an unknown quantity at this point
Thanks for your response.

I did notice that if I were to do this:

main()
{
      Cat aRovert[300000];
    //Car aRovert[30000];  this would work. 
    system("PAUSE");
    return EXIT_SUCCESS;
}

my program would crash. Whereas, this:

main()
{
     Cat *aRover[300000];
    
         for (int i = 0; i < 300000; i++)
         {
            aRover[i] = new Cat; 
         }
    system("PAUSE");
    return EXIT_SUCCESS;
}
wouldn't crash my program.


Furthermore, the crash would happend right as I launched the program. As opposed to getting to a specific point then crashing.

In case you want the class, here it is:

#include <iostream>

using namespace std;

//int main(int argc, char *argv[])

class Animal 
{
      public:
      Animal () {cout << "In Animal Constructor \n";}
      ~Animal () {cout << "In Animal Destructor \n";}
      void setAge(int age){itsAge = age;}
      int getAge(){return itsAge;}
      
      virtual void doSomething() {cout << "doing animal things";}
      
      protected:
      int itsAge;
};

class Cat : public Animal
{
      public:
      Cat() {cout << "Cat constructor \n";}
      ~Cat() {cout << "Cat destructor \n";}
      
      void doSomething () {cout << "Meow \n";}
      void JumpHigh () {cout << "Jumping high";}
      
      protected:
      int itsHealth;
};

Is this not a symptom of having less memory on the stack then on the heap?
__________________
Death smiles at us all. All a man can do is smile back.
Eric the Red is offline   Reply With Quote
Old Oct 23rd, 2006, 9:05 PM   #4
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Cat *aRover[300000];
defines an array of 300,000 pointers; for a typical 32-bit machine, 1.2 megabytes.

Cat aRover [300000];
defines an array of 300,000 Cats; a much larger quantity. Neither of those sizes are to be considered "severely limited". Severely limited is when you have to spend 3 weeks whittling out 7 bytes so you don't have to buy another 2K EEPROM in production quantities. That's at old sizes and old prices, but you get the picture.

If you need housing for 300,000 cats, you should consider spaying/neutering .

As I mentioned, the heap is available for multiple processes. If everyone used their share fairly, or if you added all the stack made available for ALL processes, you'd probably recognize the equality.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Oct 24th, 2006, 11:53 AM   #5
Eric the Red
Hobbyist Programmer
 
Eric the Red's Avatar
 
Join Date: Feb 2006
Posts: 214
Rep Power: 0 Eric the Red is an unknown quantity at this point
Okay, thank you.

Now, considering that the application crashes when I make 300,000 cats, wouldn't that be a problem in real life situations or am I simply leaving something out. For instance, using a database to do this kind of work?

main()
{
      Cat aRovert[300000];
    //Car aRovert[30000];  this would work. 
    system("PAUSE");
    return EXIT_SUCCESS;
}
__________________
Death smiles at us all. All a man can do is smile back.
Eric the Red is offline   Reply With Quote
Old Oct 24th, 2006, 1:11 PM   #6
Narue
Professional Programmer
 
Narue's Avatar
 
Join Date: Sep 2005
Posts: 419
Rep Power: 3 Narue is on a distinguished road
>Now, considering that the application crashes when I make 300,000 cats, wouldn't that be a problem in real life situations
Well designed applications avoid that kind of situation by dividing data sets into manageable pieces. Two good examples are streaming and persistence. If you only need one item at a time then you can stream through the items one by one either by generating or retrieving them, processing them, and then reclaiming or reusing the memory for the next item. If you don't have to have RAM-speed access for every item in the entire set all at once, you can persist most of the set to disk and keep a cache of a much smaller set for quick access.

If you do have to have RAM-speed access for every item in a data set all at once and the size breaks your application, you can start looking for another job because you'll get fired with solutions like that.
__________________
Even if the voices aren't real, they have some pretty good ideas.
Narue is offline   Reply With Quote
Old Oct 24th, 2006, 1:59 PM   #7
Eric the Red
Hobbyist Programmer
 
Eric the Red's Avatar
 
Join Date: Feb 2006
Posts: 214
Rep Power: 0 Eric the Red is an unknown quantity at this point
Quote:
Originally Posted by DaWei View Post
Cat *aRover[300000];
defines an array of 300,000 pointers; for a typical 32-bit machine, 1.2 megabytes.

Cat aRover [300000];
defines an array of 300,000 Cats; a much larger quantity. Neither of those sizes are to be considered "severely limited". Severely limited is when you have to spend 3 weeks whittling out 7 bytes so you don't have to buy another 2K EEPROM in production quantities. That's at old sizes and old prices, but you get the picture.

If you need housing for 300,000 cats, you should consider spaying/neutering .

As I mentioned, the heap is available for multiple processes. If everyone used their share fairly, or if you added all the stack made available for ALL processes, you'd probably recognize the equality.

Sorry, I meant

Cat * aRover = new Cat[300000]; // doesn't crash program

//Cat aRovert[300000]; // does crash program.

The first line doesn't crash the program. While, if don't comment out the second line, it crashes.
__________________
Death smiles at us all. All a man can do is smile back.
Eric the Red is offline   Reply With Quote
Old Oct 24th, 2006, 2:39 PM   #8
lectricpharaoh
Caffeinated Neural Net
 
lectricpharaoh's Avatar
 
Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 1,005
Rep Power: 5 lectricpharaoh will become famous soon enough
Quote:
Originally Posted by Eric the Red View Post
Sorry, I meant

Cat * aRover = new Cat[300000]; // doesn't crash program

//Cat aRovert[300000]; // does crash program.
The first line doesn't crash the program. While, if don't comment out the second line, it crashes.
Again, the first declares a bunch of pointers, whereas the second declares a bunch of Cat objects. Try adding this to see the difference:
std::cout << "300000 pointers to Cat = " << 300000 * sizeof(Cat*) << " bytes needed\n";
std::cout << "300000 actual Cat objects = " << 300000 * sizeof(Cat) << " bytes needed\n";
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot.
- Vaarsuvius, Order of the Stick
lectricpharaoh is offline   Reply With Quote
Old Oct 24th, 2006, 3:18 PM   #9
Eric the Red
Hobbyist Programmer
 
Eric the Red's Avatar
 
Join Date: Feb 2006
Posts: 214
Rep Power: 0 Eric the Red is an unknown quantity at this point
Quote:
Originally Posted by lectricpharaoh View Post
Again, the first declares a bunch of pointers, whereas the second declares a bunch of Cat objects.
You're incorrect, unless this book is wrong again... ROFL.

This:
Quote:


Cat * aRover = new Cat[300000];

Declares a pointer to an array of 300000 Cats. "the address in the pointer aRover is the adress of the first item in that array" (my book)

Whereas, this.. as Dawei said
Cat *aRover[300000];

Defines an array of 300,000 pointers to Cats.
__________________
Death smiles at us all. All a man can do is smile back.
Eric the Red is offline   Reply With Quote
Old Oct 24th, 2006, 3:36 PM   #10
Narue
Professional Programmer
 
Narue's Avatar
 
Join Date: Sep 2005
Posts: 419
Rep Power: 3 Narue is on a distinguished road
>The first line doesn't crash the program. While, if don't comment out the second line, it crashes.
As expected. You can only declare an array of a certain size before it trashes your computer. The second line creates such an array while the first line doesn't create an array at all. It simply allocates a block of dynamic memory and points a pointer to it. If you don't mind me being inaccurate for the sake of simplicity, it goes like this:

Anything you create with new is on the heap, and the heap is virtually (haha! I made a funny) limitless.
Anything else is on the stack, and the stack is very limited by comparison.
__________________
Even if the voices aren't real, they have some pretty good ideas.
Narue is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Combining languages titaniumdecoy Other Programming Languages 12 Jul 13th, 2006 2:03 PM
Assembly tutorial, part one. Mad_guy Software Design and Algorithms 21 Apr 15th, 2006 7:02 PM
A noob to Assembly CodeJunkie Assembly 12 Jan 25th, 2006 2:06 PM
STACK- acessing argc and argv outside main() mguarin C 9 Oct 28th, 2005 8:38 PM
Pointers in C (Part I) Stack Overflow C 4 Apr 28th, 2005 7:03 PM




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 9:28 AM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC