Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
C++ Game Development Cookbook

You're reading from   C++ Game Development Cookbook

Arrow left icon
Product type Paperback
Published in May 2016
Publisher Packt
ISBN-13 9781785882722
Length 346 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Druhin Mukherjee Druhin Mukherjee
Author Profile Icon Druhin Mukherjee
Druhin Mukherjee
Arrow right icon
View More author details
Toc

Table of Contents (15) Chapters Close

Preface 1. Game Development Basics FREE CHAPTER 2. Object-Oriented Approach and Design in Games 3. Data Structures in Game Development 4. Algorithms for Game Development 5. Event-Driven Programming – Making Your First 2D Game 6. Design Patterns for Game Development 7. Organizing and Backing Up 8. AI in Game Development 9. Physics in Game Development 10. Multithreading in Game Development 11. Networking in Game Development 12. Audio in Game Development 13. Tips and Tricks Index

Managing memory more effectively using dynamic allocation

Programmers generally deal with five areas of memory: global namespace, registers, code space, stack, and the free store. When an array is initialized, the number of elements has to be defined. This leads to lots of memory problems. Most of the time, not all elements that we allocated are used, and sometimes we need more elements. To help overcome this problem, C++ facilitates memory allocation while an .exe file is running by using the free store.

The free store is a large area of memory that can be used to store data, and is sometimes referred to as the heap. We can request some space on the free store, and it will give us an address that we can use to store data. We need to keep that address in a pointer. The free store is not cleaned up until your program ends. It is the programmer's responsibility to free any free store memory used by their program.

The advantage of the free store is that there is no need to preallocate all variables. We can decide at runtime when more memory is needed. The memory is reserved and remains available until it is explicitly freed. If memory is reserved while in a function, it is still available when control returns from that function. This is a much better way of coding than global variables. Only functions that have access to the pointer can access the data stored in memory, and it provides a tightly controlled interface to that data.

Getting ready

For this recipe, you will need a Windows machine with a working copy of Visual Studio.

How to do it…

In this recipe, we will see how easy it is to use dynamic allocation. In games, most of the memory is allocated dynamically at runtime as we are never sure how much memory we should assign. Assigning an arbitrary amount of memory may result in less memory or memory wastage:

  1. Open Visual Studio.
  2. Create a new C++ project.
  3. Add a source file called main.cpp or anything that you want to name the source file.
  4. Add the following lines of code:
    #include <iostream>
    #include <conio.h>
    #include <string>
    
    using namespace std;
    
    int main()
    {
    
      int iNumberofGuns, iCounter;
      string * sNameOfGuns;
      cout << "How many guns would you like to purchase? ";
      cin >> iNumberofGuns;
      sNameOfGuns = new string[iNumberofGuns];
      if (sNameOfGuns == nullptr)
        cout << "Error: memory could not be allocated";
      else
      {
        for (iCounter = 0; iCounter<iNumberofGuns; iCounter++)
        {
          cout << "Enter name of the gun: ";
          cin >> sNameOfGuns[iCounter];
        }
        cout << "You have purchased: ";
        for (iCounter = 0; iCounter<iNumberofGuns; iCounter++)
          cout << sNameOfGuns[iCounter] << ", ";
        delete[] sNameOfGuns;
      }
    
      _getch();
      return 0;
    }

How it works…

You can allocate memory to the free store using the new keyword; new is followed by the type of the variable you want to allocate. This allows the compiler to know how much memory will need to be allocated. In our example, we have used string. The new keyword returns a memory address. This memory address is assigned to a pointer, sNameOfGuns. We must assign the address to a pointer, otherwise the address will be lost. The format for using the new operator is datatype * pointer = new datatype. So in our example, we have used sNameOfGuns = new string[iNumberofGuns]. If the new allocation fails, it will return a null pointer. We should always check whether the pointer allocation has been successful; otherwise we will try to access a part of the memory that has not been allocated and we may get an error from the compiler, as shown in the following screenshot, and your application will crash:

How it works…

When you are finished with the memory, you must call delete on the pointer. Delete returns the memory to the free store. Remember that the pointer is a local variable. Where the function that the pointer is declared in goes out of scope, the memory on the free store is not automatically deallocated. The main difference between static and dynamic memory is that the creation/deletion of static memory is handled automatically, whereas dynamic memory must be created and destroyed by the programmer.

The delete[] operator signals to the compiler that it needs to free an array. If you leave the brackets off, only the first element in the array will be deleted. This will create a memory leak. Memory leaks are really bad as it means there are memory spaces that have not been deallocated. Remember, memory is a finite space, so eventually you are going to run into trouble.

When we use delete[], how does the compiler know that it has to free n number of strings from the memory? The runtime system stores the number of items somewhere it can be retrieved only if you know the pointer sNameOfGuns. There are two popular techniques that do this. Both of these are used by commercial compilers, both have tradeoffs, and neither are perfect:

  • Technique 1:

    Over-allocate the array and put the number of items just to the left of the first element. This is the faster of the two techniques, but is more sensitive to the problem of the programmer saying delete sNameOfGuns, instead of delete[] sNameOfGuns.

  • Technique 2:

    Use an associative array with the pointer as a key and the number of items as the value. This is the slower of the two techniques, but is less sensitive to the problem of the programmer saying delete sNameOfGuns, instead of delete[] sNameOfGuns.

There's more…

We can also use a tool called VLD to check for memory leaks.

Note

Download VLD from https://vld.codeplex.com/.

After the setup has downloaded, install VLD on your system. This may or may not set up the VC++ directories correctly. If it doesn't, do it manually by right-clicking on the project page and adding the directory of VLD to the field called Include Directories, as shown in the following figure:

There's more…

After setting up the directories, add the header file <vld.h> in your source file. After you execute your application and exit it, your output window will now show whether there are any memory leaks in your application.

Understanding the error messages

When using the debug build, you may notice the following values in memory during debugging:

  • 0xCCCCCCCC: This refers to values being allocated on the stack, but not yet initialized.
  • 0xCDCDCDCD: This means memory has been allocated in the heap, but it is not yet initialized (clean memory).
  • 0xDDDDDDDD: This means memory has been released from the heap (dead memory).
  • 0xFEEEFEEE: This refers to values being deallocated from the free store.
  • 0xFDFDFDFD: "No man's land" fences, which are placed at the boundary of heap memory in debug mode. These should never be overwritten, and if they are, it probably means the program is trying to access memory at an index outside of an array's max size.
You have been reading a chapter from
C++ Game Development Cookbook
Published in: May 2016
Publisher: Packt
ISBN-13: 9781785882722
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime