Академический Документы
Профессиональный Документы
Культура Документы
What is memory?
Think of it as a giant array
0xffffffff
Stack Segment
0x00000000
Heap Segment for dynamic data (whenever you use new) data for constructed objects (new) persistent as long as an existing object variable references this region of memory
Global Segment data that can be reserved at compile time
Heap Segment
Global Segment
Global Functions & Variables Functions which are not methods of a class
like printf & main on the previous slide
Make sure you dont create a duplicate method signature or duplicate global variables
public class PhoneListing { public int number = 0; public String name = "NONE";//global public PhoneListing() {}
public static void main(String[] args) { test1(); } public static void test1() { PhoneListing test = new PhoneListing(); //heap, 8 bytes Where will test be stored? test.number = 8675309; How much memory test.name = new String("Jenny"); will be reserved? printDetails(test); } public static void printDetails(PhoneListing d)//phonelisting d goes on stack {
Language Shifts
Game developers should continually look to take advantage of the latest advances (including changing languages)
language shifts approximately every 10 years the truth is most programmers use one language for most of their career. Why?
either they dont want to, or their employer doesnt want to
To prevent C & C++ from becoming the obstacle to learning to build game technologies What will we cover?
Text Arrays & structs Pointers Call by Value vs Call by Reference Objects & classes Inheritance
Where do we start?
Hello World of course 1. Start Visual C++ 2. Select: New Project Visual C++ Win32 Project 3. Name your project HelloWorld 4. Place it on your desktop 5. Click OK and then Finish buttons
What do we get? a mess, try running it welcome to the world of Windows programming
int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { dialogText[0] = '\0'; wcscat(dialogText, L"Hello"); wcscat(dialogText, L"\nWorld!");
wchar_t dialogTitle[25]; dialogTitle[0] = '\0'; wcscat(dialogTitle, L"Wide Characters"); MessageBox(NULL, dialogText, dialogTitle, MB_OK);
MessageBox method
From Windows library Similar to JOptionPane in Java, but no text input Many customizable dialog types
set type
http://msdn2.microsoft.com/en-us/library/ms645505.aspx
Ex, to get button selection from user, add the code on the following page to HelloWorld BTW, well never use this again
Whats a wchar_t?
A C++ type
Also some Windows methods: _itow: int to wchar_t array _wtoi: wchar_t array to int _wtof: wchar_t array to float
Text Exercise
Make a program that does the following:
1. Selects a random int from 1 to 100 2. Loads the int into a wchar_t array 3. Displays the text in a MessageBox
For example, for a random number 100 200: int num = (rand() % 101) + 100;
Arrays
Weve used them already
In C++, you can put an array on the stack, global region, or the heap
which ones have we done so far?
global (dialogText) the stack (dialogTitle)
Exercise
Change your program such that all array data goes on the heap Note: data goes on the heap when you call new new: constructs an object/array and returns a memory address (pointer) to that location
just like in Java
Run the program Also, open the task manager (CTRL ALT DEL) Is there a memory leak?
Ever used C?
Java inherited much from C
similar primitives (not entirely the same) similar conditional statements similar loops
Pointers
In Java, what do object variables store?
memory addresses this makes them pointers what do they point to?
object data on the heap
*
* is a C operator used for 2 purposes:
1. To declare a variable as a pointer. Ex:
int *myIntPointer; right now, myIntPointer points to a random address trying to use before initialization results in a segmentation fault or bus error
&
A C operator used for getting the address of a variable
Call-by-value
In Java, when you pass an argument to a method, you are actually passing a copy of that argument
this is called call-by-value
Ex:
public static void main(String[] args) { int x = 5; junk(x); System.out.println("x is " + x); } public void junk(int argument) { argument++; }
OUTPUT: x is 5
Ex:
void junk(int cbv, int *cbr); OUTPUT: int main() x is 5 { int x = 5; y is 7 int y = 6; junk(x, &y); printf("x is %d\ny is %d\n", x, y); } void junk(int cbv, int *cbr) { cbv++; (*cbr)++;
So, assigning an address to the pointer would not change the original pointer
OUTPUT: x is 5
struct Point { int x; int y; }; void changePoint(struct Point p); int main() { OUTPUT: struct Point p1; p1.x = 100; p1.x is 100 p1.y = 200; p1.y is 200 changePoint(p1); printf("p1.x is %d\np1.y is %d\n", p1.x, p1.y); } void changePoint(struct Point p) { We just changed p, a p.x *= 5; copy of p1, but not p1 p.y *= 4; }
struct Point { int x; int y; }; void changePoint(struct Point p); int main() { OUTPUT: struct Point p1; p1.x = 100; p1.x is 500 p1.y = 200; p1.y is 800 changePoint(&p1); printf("p1.x is %d\np1.y is %d\n", p1.x, p1.y); } void changePoint(struct Point *p) { We just changed p, and (*p).x *= 5; so changed p1 (*p).y *= 4; }
struct Point { int x; int y; }; void changePoint(struct Point p); int main() { struct Point *p1 = makePoint(); printf("p1.x is %d\np1.y is %d\n", (*p1).x, (*p1).y); } struct Point* makePoint() What happens? { struct Point p1; p1.x = 100; DISASTER! WHY? p2.y = 200; return &p1; } When makePoint ends, p1
Who cares?
you should if you want your program to run efficiently
Whats free?
a method that releases the memory block argument
struct Point { int x; NOW IT WORKS int y; }; void changePoint(struct Point p); int main() { struct Point *p1 = makePoint(); printf("p1.x is %d\np1.y is %d\n", p1->x, p1->y); } struct Point* makePoint() { struct Point *p1; p1 = malloc(sizeof(struct Point)); (*p1).x = 100; (*p2).y = 200; return p1; }
->
Used to dereference data in a pointer to a struct or array. Ex:
struct Point { int x; int y; }; int main() { int pointBytes = sizeof(struct Point); struct Point *p = malloc(pointBytes); p->x = 10; p->y = 20; printf("x is %d\ny is %d\n", p->x, p->y); free(p); }
Memory Leak! (thats a bad thing) - note, by the time this loop ends, your program will be using up 8 bytes * 10000 = 80000 bytes of memory for one p variable - whered I get 8 bytes from?
char* as an array
char *text; text = malloc(sizeof(char) * 4); int i; for (i = 0; i < 3; i++) text[i] = (char)(65 + i); text[3] = '\0'; printf("text is %s\n", text);
Output: text is ABC
text2[0] = malloc(sizeof(char) * 4); for(i = 0; i < 3; i++) text2[0][i] = (char)(i + 65); text2[0][3] = '\0'; printf("text2[0] is %s\n", text2[0]);
text2[1] = malloc(sizeof(char) * 6); for(i = 0; i < 5; i++) text2[1][i] = (char)(i + 68); text2[0][5] = '\0'; printf("text2[1] is %s\n", text2[1]);
Array of structs
struct Point *points; int numPoints = 5; points = malloc(sizeof(struct Point) * numPoints); int i; bash-2.05$ ./StructArraysTester srand(time(NULL)); points[0] = (597,209) for (i = 0; i < numPoints; i++) points[1] = (41,800) { points[2] = (464,96) points[3] = (59,892) points[i].x = rand() % 1000; points[4] = (418,231) points[i].y = rand() % 1000; printf("points[%d] = (%d,%d)\n", i, points[i].x, points[i].y); }
Segmentation Fault
One of the most common C errors
Means you are trying to access a place in memory that you do not have permission to access
Typical problems:
accessing uninitialized pointer improper pointer arithmetic
malloc gets passed the # of bites to allocate free does not get passed such info
this info exists in library methods, but we dont have access to it
To track memory allocation, we can define our own memory allocation/deallocation methods
What else?
when mallocing, add a little extra memory for some header info when freeing, extract header info what kind of info?
size of allocation checksum for error checking
Why do we care?
we need to stick our info at the front of our object
malloc_info
Our header
well stick in in front of each piece of data we allocate
We can total memory usage in global variables totalAlloc, totalFreed, dataAlloc, & dataFreed
#define MALLOC_CHECKSUM 123456789 struct malloc_info { int checksum; size_t bytes; }; long totalAlloc, totalFreed, dataAlloc, dataFreed;
void* our_malloc(size_t bytes) { void *data; struct malloc_info *info; data = malloc(bytes + sizeof(struct malloc_info)); if (!data) return NULL; else { size_t headerSize = sizeof(struct malloc_info); totalAlloc += bytes + headerSize; dataAlloc += bytes; info = (struct malloc_info *)data; info->checksum = MALLOC_CHECKSUM; info->bytes = bytes; char *data_char = (char*)data; data_char += headerSize; return (void*)data_char; } }
void our_free(void *data) { struct malloc_info *info; void *data_n_header; size_t header_size = sizeof(struct malloc_info); char *data_char = (char*)data; data_char = data_char - header_size; data_n_header = (void*)data_char; info = (struct malloc_info *)data_n_header; if (info->checksum != MALLOC_CHECKSUM) throw std::bad_alloc(); totalFreed += info->bytes + sizeof(struct malloc_info); dataFreed += info->bytes; free(data_n_header); }
So what?
So we can monitor the following differences:
totalAlloctotalFreed dataAllocdataFreed
Hello.h // declare a class Hello class Hello { public: // begin the public section Hello(); // declare a constructor private: // begin the private section int num; // declare an instance variable }; Hello.cpp #include Hello.H" Hello::Hello() // definition of Hello constructor { num = 5; // the constructor initializes num }
Inlining methods Method definitions may be placed inside header files (.h) Huh? When done, these methods are inlined
Whats that?
Pointers
In Java, what do object variables store?
memory addresses this makes them pointers what do they point to?
object data on the heap
Have Class A have an instance variable of type Class B Have Class B have an instance variable of type Class A Whats the problem?
Virtual Functions In Java, all method are virtual (results in a bit of overhead)
allows for methods to be overridden in a child class
Purely Virtual Methods Like abstract methods in Java Require a child class to override a method Method does nothing on its own To specify, add = 0 after the parameter list in a function declaration Ex:
class Foo { public: virtual int abstractMethod() = 0; };
Memory Management Java uses automatic garbage collection & memory management Convenient for the programmer Slow for performance C++ allows for memory management via:
Pointers Constructors & destructors Allocation & de-allocation of memory
Pointers
Stores the memory address of a variable Denoted by *
tells the compiler we want it to be a pointer when we declare it
Ex:
int* myIntPointer;
int* myIntegerPointer; int myInteger = 1000; myIntegerPointer = &myInteger; printf("myIntegerPointer = %d\n", myIntegerPointer); printf("myIntegerPointer = %d\n", *myIntegerPointer);
1005
== myIntegerPointer
Why do we care about pointers? Declaring and assigning objects Object constructors return addresses Correct C++ syntax to declare and assign a Foo object pointer:
Foo* myFooInstance = new Foo(0, 0); OR, for just the object: Foo myFooInstance(0, 0);
Using objects I can declare an object and use the . operator to call methods: Foo myInstance; myInstance.someMethod(); NOTE: the same is not true for object pointers
Freeing up memory Java has a garbage collector It looks for all the constructed objects you dont need anymore
frees up that memory
In C++, you must collect your object garbage What if you dont?
memory leak in a game, it will kill performance
How?
use delete keyword on object pointers
Good rules of thumb: 1. memory allocated in a function should be deallocated before it exits 2. memory allocated in a constructor should be deallocated in a destructor
Class Destructors Executed when an instance of a class is destroyed For Foo class, would be ~Foo() What should it do?
delete all object instance variables
Ex:
class Foo { private: Bar* m_barPtr; public: Foo() { m_barPtr = new Bar; } ~Foo() { delete m_barPtr; }
Exercise
Define a class that represents an Employee name, id number ,salary, accessors/mutators Define another class that represents a Payroll has an array of Employees, methods for adding and calculating total payroll salary How many? It might get bigger Write a small program that constructs a Payroll and loads it with 5 Employees, making 20,000, 30,000, 40,000, 50,000, and 60,000 Have your program calculate and then display the Payrolls total salary in a MessageBox