• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
akira2000

stack vs heap

31 posts in this topic

Hello.

 

I'm working as java programmer and just now starting to learn c++ and irrlicht (want to create games as a hobby ;) ).

I am completely confused by stack vs heap issue.

What is the advantage of using heap? Isn't it MUCH faster and more efficient to create variales on stack and pass them by reference.

What I mean is:

 

Object obj = new Object();

 

VERSUS

 

Object obj;

method1(&obj)

 

I am also confused by memory managment in c++. When stack object is freed is there a memory "hall" in stack.  

 

Thanks 

0

Share this post


Link to post
Share on other sites

Hello.

 

I'm working as java programmer and just now starting to learn c++ and irrlicht (want to create games as a hobby ;) ).

I am completely confused by stack vs heap issue.

What is the advantage of using heap? Isn't it MUCH faster and more efficient to create variales on stack and pass them by reference.

What I mean is:

 

Object obj = new Object();

 

VERSUS

 

Object obj;

method1(&obj)

 

I am also confused by memory managment in c++. When stack object is freed is there a memory "hall" in stack.  

 

Thanks 

Generally in C++ if you want by reference passing of variables you define this in the function header not in it's use.

 

 

void functionByReference(const Object& obj);
void functionByPointer(const Object* obj); //In compiled code(asm) there is no difference between this call and the one above it, the compiler does see this differently though.
void functionByValue(const Object obj);
 
//Both are called as follows
Object object;
functionByReference(object); //This call is faster then the one below it
functionByValue(object);
 
functionByPointer(&object); //You have to use the address operator here because the function is expecting a pointer to an object

 

Usually you only feed a function a "&<variable>" when you only have a stack value and the function wants a object that's passed by pointer. Even when the variable is an output parameter this is expressed in the function header and not in it's use.

Edited by NightCreature83
1

Share this post


Link to post
Share on other sites

The language in NightCreature83's post is not completely clear, so let me clarify. There is no notion of "function header": He probably meant to say "function prototype".

 

C++ has no notion of output parameter. If you want to use a parameter for output, you can make it a reference or a pointer. If you make it a reference, the code that calls the function will be indistinguishable from passing by value or by `const' reference. If you made it a pointer, the code would look just the way the OP posted (with the `&'). That's why I usually prefer to get a pointer for variables I intend to modify.

2

Share this post


Link to post
Share on other sites
Another place you will often want heap allocation is when you are using polymorphism.
0

Share this post


Link to post
Share on other sites

OK biggrin.png  Now it's MUCH clearer. 

As I see it now, I should use stack vars if and only if it's life span does NOT need to exceed the scope of it's creation {}. 

Also, a "little" advantage of heap vars is that I can free them in the "middle" of the scope, thus the memory usage is a little smaller.

Ok! I will use stack vars where I can !

Thank you all for the valuable answers :) 

0

Share this post


Link to post
Share on other sites

Furthermore, stack memory should be avoided when dealing with large sets of data since most operating systems gives a limit for stack allocation (something in the order of 10mb from my experience), so if you try to declare an data array of size bigger than 10mb for example, your program will most likely crash.

 

Thought it would be worth mentioning since it's a bug very difficult to catch. I don't know what are the workarounds for that so I only use heap for large data allocation.

1

Share this post


Link to post
Share on other sites

Furthermore, stack memory should be avoided when dealing with large sets of data since most operating systems gives a limit for stack allocation (something in the order of 10mb from my experience), so if you try to declare an data array of size bigger than 10mb for example, your program will most likely crash.

 

Thought it would be worth mentioning since it's a bug very difficult to catch. I don't know what are the workarounds for that so I only use heap for large data allocation.

 

0.o are you sure about this one? In java, for example, I do sometimes have objects of this size. When I work with images, pdfs...

So I should create objects on stack only if their size < X ??? 

0

Share this post


Link to post
Share on other sites

Furthermore, stack memory should be avoided when dealing with large sets of data since most operating systems gives a limit for stack allocation (something in the order of 10mb from my experience), so if you try to declare an data array of size bigger than 10mb for example, your program will most likely crash.

 

Thought it would be worth mentioning since it's a bug very difficult to catch. I don't know what are the workarounds for that so I only use heap for large data allocation.

 

0.o are you sure about this one? In java, for example, I do sometimes have objects of this size. When I work with images, pdfs...

Java isn't allocating that memory on the stack. It's allocating it on the heap.

 

So I should create objects on stack only if their size < X ??? 

If you are dealing with large objects (like large arrays), you should allocate them on the heap. Besides, I've typically found that if I need a (potentially) large array, it's probably a dynamically sized array too, so allocating it on the stack at compile time makes very little sense.

2

Share this post


Link to post
Share on other sites

You can test it yourself, start by declaring a small vector and keep increasing it's size.

 

float hum[100000];

float hum[1000000];

float hum[10000000];

 

Eventually you'll reach a "segmentation fault" error.

 

I can't ensure you of this fact, since I could have done some wrong compiler configuration or my O.S (Ubuntu) deals with memory management in a different way, so I'll leave to more experienced programmers to elaborate on this. I had this issue once and it was very hard to figure it out.

 

Let me know what yo find.

1

Share this post


Link to post
Share on other sites

In java, for example, I do sometimes have objects of this size

 

You can have. Java uses the heap too.

 

Your "X" varies from system to system, plus depends on how much stuff you have on the stack already(e.g are you using recursions or not). 

1

Share this post


Link to post
Share on other sites

You can test it yourself, start by declaring a small vectorarray and keep increasing it's size.

Fixed that for you ;)

2

Share this post


Link to post
Share on other sites

Even if you use the heap, there is rarely a reason to do so by directly writing `new' and `delete' in your program. For instance, if I need a large array (or if I am not too sure what size it will have) I use std::vector, which will allocate its data on the heap, but it does so using RAII (an acronym that never made sense to me, but it means the destructor takes care of things). If I need polymorphism, I use a smart pointer (unique_ptr, most likely) that also uses RAII.

 

There are still ways to leak memory when you program this way, but it's hard.

0

Share this post


Link to post
Share on other sites

Another pitfall to look out for (one that seems obvious but have seen before)  - when passing by reference and also maybe using locals is never return a reference to local data when returning from a function.  Of course, the data will be popped off the stack and won't exist any more.  Reads will provide "bad" data (i.e. whatever happens to be on that stack location) and writes can really screw things up!!

0

Share this post


Link to post
Share on other sites

You can try what Hodgman said by something like this (I just find this a bit more clear!)

 

class MyClass
{
public:
	MyClass()
	{
		memset( &m_szName, 0, sizeof(m_szName) );
		strcat_s( m_szName, "I'm an object!" );
	}

	~MyClass()
	{
	}

public:
	char m_szName[64];
};

void DoSomethingHere()
{
	printf( "DoSomethingHere()\n" );
}

void DoSomethingElseHere( MyClass var )
{
	printf( var.m_szName );
	printf( "\n" );
}

void DoAnotherThingHere( MyClass var )
{
	memset( var.m_szName, 0, sizeof(var.m_szName) );
	strcat_s( var.m_szName, "Rewriting var.m_szName" );
	printf( var.m_szName );
	printf( "\n" );
}

int _tmain(int argc, _TCHAR* argv[])
{
	DoSomethingHere();

	{
		MyClass obj;
		DoSomethingElseHere( obj );
	}

	DoAnotherThingHere( obj );

	Sleep( 50000 );

	return 0;
}

 

 

And yes, there are certain benefits you can abuse by using code blocks like above (eg; a large command table).

Visual Studio gave me an error that obj is undefined when trying to call "DoAnotherThingHere", letting me know that "obj" would no longer exist after it has executed passed that end-codeblock.

 

Along the way, you'll understand when to allocate on the stack or the heap.

Edited by MarlboroKing
0

Share this post


Link to post
Share on other sites
Are you sure about that overflow-by-array problem? I would think the compiler would just make the stack large enough. Isn't required stack length included in the module header?
0

Share this post


Link to post
Share on other sites

Isn't required stack length included in the module header?

I am not entirely sure what you mean by that, but no: The stack size is usually determined by the OS. For instance, if you are using the bash shell in Linux, you can set the stack size for new processes using `ulimit -s <number_of_kilobytes>'.
0

Share this post


Link to post
Share on other sites

About shared_ptr. I read now that that Bjarne consider this as bad idea and this is considered as bad c++ design pattern. Anyone can put some light on this.

About unique_ptr. I do NOT want to write managed code. Is unique_ptr managed code ???

0

Share this post


Link to post
Share on other sites

Some compilers allow segmented stacks, which do not have limits on size and the stack can grow just like heap variables. Some can also convert large stack arrays to heap arrays.

0

Share this post


Link to post
Share on other sites

Generally the whole point of the heap is to allow you to have precise control over when you allocate and deallocate memory. Obviously you can't just exit function calls constantly to free memory, especially if something runs in a tight loop and parts of the reserved memory need to stay in use and others need to be freed as you go. For games this is an obvious one since you get things like "permanent" entities in the world that need to be removed when they are no longer used.

 

I've noticed most people here recommend using smart pointers simply because it adds things like reference counting which is minute overhead for the benefit of the memory freeing itself when no longer needed, but, honestly, it all comes down to your needs. There's no strict reason you HAVE to use a smart pointer, in fact you can free allocate and free things and null pointers whenever you like, but its on your head if something gets missed.

1

Share this post


Link to post
Share on other sites

if your writing a real time game, I would recommend an entirely different approach:

 

code should be C, not C++. No OO, no virtual methods, no mallocs (new, etc), no polymorphism. none of that slow stuff!

 

vars should be passed by reference with the fastcall convention and no stack frame.

 

the size limit for the stack segment supposedly went away years ago (at least in windows OS), so you should be able to declare huge arrays locally in a procedure without exceeding stack segment size. If its still an issue, simply do a malloc at procedure start and a free at procedure end.

 

whenever possible, declare data structures as global statics. instead of new-ing and disposing a bunch of objects for NPCs all the time, have a global array[MAXNPCS] with an active field in the struct. always use arrays vs linked lists. in general, always do whats fast, not whats considered "correct" by non-game programming standards. if its the "correct" way to do things in the real programming world, odds are its totally wrong for high performance real time games.

 

do you have any idea exactly what happens (at the instruction set and clock cycle count level) when you create an object? talk about SLOW code!

 

remember OO was invented for people who couldn't write ADT (abstract data type) style non-spaghetti code, and as a slicker way to encapsulate variant records and procedural variables. It has nothing to do with writing games that run fast. May make it easier (for some) to write code, but slower code on average, unfortunately.

 

like most things in game development, there's the easy way and the fast way to do it. if you code each line with clock cycles in mind form the get go, you'll have very little optimization to do at the end. 

-16

Share this post


Link to post
Share on other sites

if you code each line with clock cycles in mind form the get go, you'll have very little optimization to do at the end. 

This is absolutely true, because you'll probably never finish your game. You probably won't even get 5% of it done by the time you (hopefully) realized you've seriously screwed up and are prioritizing horribly wrong. And by then, your code will be so defunct you might as well start over from scratch. So yes, very little optimization to do at the end indeed, because you won't reach the end.

 

FWIW, optimizations should be focused on algorithmic optimizations. Optimizing a single line of code (or a bunch of lines individually) will likely have very little effect on your program's performance (the rare exceptions are incredibly tight loops that are known to be significant bottle necks (known after profiling)).

 

And Norman, you're insanea complete troll if you seriously think you shouldn't use any dynamic memory allocation. Yeah, definitely a troll. Not even gonna try to respond to your post anymore.

2

Share this post


Link to post
Share on other sites
You should optimize your code for clarity first and correctness second. Regarding performance, think about what algorithms and data structures you use, avoid writing code that you know will be slow, and then only optimize something for performance if your program is too slow and you have a profiler run indicating this is where optimization is needed.

You'll get much further with this advice than with the optimize-every-line nonsense from a few posts above this one. Edited by Álvaro
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0