CSCI 104 Memory Allocation: Mark Redekopp David Kempe
CSCI 104 Memory Allocation: Mark Redekopp David Kempe
Memory Allocation
Mark Redekopp
David Kempe
VARIABLES & SCOPE
2
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
A Program View of Memory
Code usually sits at low addresses
Global variables somewhere after code 0
Code
System stack (memory for each function
instance that is alive) …
…
– Return link (where to return)
– etc.
Heap
Heap: Area of memory that can be allocated
and de-allocated during program execution
(i.e. dynamically at run-time) based on the
…
needs of the program
Heap grows downward, stack grows upward…
…
– In rare cases of large memory usage, they Stack
(area for
could collide and cause your program to fail or data local to
a function)
generate an exception/error fffffffc
Memory
3
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Variables and Static Allocation
Every variable/object in a computer Code Computer
has a:
– Name (by which programmer references it) int x;
x
– Address (by which computer references it) string s1("abc"); 0x1a0 -154729832
– Value s1
Let's draw these as boxes 0x1a4 3 "abc"
Every variable/object has scope (its
main
lifetime and visibility to other code) int main() x
{
Automatic/Local Scope int x; 0x1a0 -154729832
if( x ){
– {…} of a function, loop, or if string s1("abc"); if
s1
– Lives on the stack }
} 0x1a4 3 "abc"
– Dies/Deallocated when the '}' is
reached
Let's draw these as nested
container boxes
4
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Automatic/Local Variables
Variables declared inside {…} are // Computes rectangle area,
// prints it, & returns it
allocated on the stack int area(int, int);
This includes functions void print(int);
int main()
Stack Area of RAM {
int wid = 8, len = 5, a;
cout a = area(wid,len);
}
0xbd8 40 area
print int area(int w, int l)
0xbdc 004001844
Return {
link
int ans = w * l;
print(ans);
0xbe0 40 ans return ans;
0xbe4 }
area 8 w
0xbe8 5 l
void print(int area)
0xbec Return
004000ca0 link {
cout << “Area is “ << area;
0xbf0 8 wid cout << endl;
0xbf4 }
main 5 len
0xbf8 -73249515 a
0xbfc Return
00400120 link
5
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Scope Example
Memory (RAM)
6
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
POINTERS & REFERENCES
7
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Pointers in C/C++
Generally speaking a "reference" can be a pointer or a C++ Reference
Pointer (type *)
– Really just the memory address of a variable
– Pointer to a data-type is specified as type * (e.g. int *)
– Operators: & and *
• &object => address-of object
• *ptr => object located at address given by ptr
• *(&object) => object [i.e. * and & are inverse operators of each other]
Example
int* p, *q; 0xbe0 p 0xbe0 0xbe8 p
int i, j;
0xbe4 q
i = 5; j = 10; 0xbe8
0xbe8 5 i
p = &i;
cout << p << endl; 0xbec 10 j 5
cout << *p << endl;
*p = j; 0xbe8 10 i
*q = *p;
q = p; Undefined
0xbe4 0xbe8 q
8
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Pointer Notes
An uninitialized pointer is a pointer just waiting to cause a
SEGFAULT
NULL (defined in <cstdlib>) or now nullptr (in C++11)
are keywords for values you can assign to a pointer when it
doesn't point to anything
– NULL is effectively the value 0 so you can write:
int* p = NULL;
if( p )
{ /* will never get to this code */ }
– To use nullptr compile with the C++11 version:
$ g++ -std=c++11 –g –o test test.cpp
Expression Type
x[0]
x
myptr
*myptr
(*ourptr) + 1
myptr + 2
ourptr 10
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
References in C/C++
Reference type (type &)
“Syntactic sugar” to make it so you don't have to use pointers
– Probably really using/passing pointers behind the scenes
Declare a reference to an object as type& (e.g. int &)
Must be initialized as declaration time (i.e. can’t declare a
reference variable if without indicating what object you want to
reference)
– Logically, C++ reference types DON'T consume memory…they are
just an alias (another name) for the variable they reference
– Physically, it may be implemented as a pointer to the referenced
object but that is NOT your concern
Cannot change what the reference variable refers to once
initialized
11
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Using C++ References
ptr
0x1a0
12
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Swap Two Variables
Pass-by-value => Passes a copy
Pass-by-reference =>
– Pass-by-pointer/address => Passes address of actual variable
– Pass-by-reference => Passes an alias to actual variable (likely its
really passing a pointer behind the scenes but now you don't have
to dereference everything)
int main() int main() int main()
{ { {
int x=5,y=7; int x=5,y=7; int x=5,y=7;
swapit(x,y); swapit(&x,&y); swapit(x,y);
cout <<“x,y=“<< x<<“,”<< y; cout <<“x,y=“<< x<<“,”<< y; cout <<“x,y=“<< x<<“,”<< y;
cout << endl; cout << endl; cout << endl;
} } }
void swapit(int x, int y) void swapit(int *x, int *y) void swapit(int &x, int &y)
{ { {
int temp; int temp; int temp;
temp = x; temp = *x; temp = x;
x = y; *x = *y; x = y;
y = temp; *y = temp; y = temp;
} } }
13
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Correct Usage of Pointers
Can use a pointer to have a function // Computes rectangle area,
// prints it, & returns it
modify the variable of another int area(int, int, int*);
int main()
{
int wid = 8, len = 5, a;
area(wid,len,&a);
}
0xbf0 8 wid
main 0xbf4 5 len
40
0xbf8 -73249515 a
0xbfc Return
00400120 link
14
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Misuse of Pointers
Make sure you don't return a pointer to a // Computes rectangle area,
// prints it, & returns it
dead variable int* area(int, int);
You might get lucky and find that old
int main()
value still there, but likely you won't {
int wid = 8, len = 5, *a;
a = area(wid,len);
cout << *a << endl;
}
Stack Area of RAM
int* area(int w, int l)
{
int ans = w * l;
0xbe0 40 ans
return &ans;
area 0xbe4 8 w }
0xbe8 5 l
0xbec Return
004000ca0 link
0xbf0 8 wid
main 0xbf4 5 len
0xbe0
0xbf8 -73249515 a
0xbfc Return
00400120 link
15
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Use of C++ References
We can pass using C++ reference // Computes rectangle area,
// prints it, & returns it
The reference 'ans' is just an alias for 'a' void area(int, int, int&);
back in main
int main()
– In memory, it might actually be a pointer, but you don't {
have to dereference (the kind of stuff you have to do int wid = 8, len = 5, a;
with pointers) area(wid,len,a);
}
0xbf0 8 wid
main 0xbf4 5 len
40
0xbf8 -73249515 a =ans
0xbfc Return
00400120 link
16
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Pass-by-Value vs. -Reference
Arguments are said to be:
– Passed-by-value: A copy is made from one function and given to
the other
– Passed-by-reference: A reference (really the address) to the
variable is passed to the other function
Care needs to be taken when choosing between the
options
Pass-by-Value Benefits Pass-by-Reference Benefits
+ Protects the variable in the + Allows another function to
caller since a copy is made (any modify the value of variable in
modification doesn’t affect the the caller
original) + Saves time vs. copying
17
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Pass by Reference
Notice no copy of x need be made since // Computes rectangle area,
// prints it, & returns it
we pass it to sum() by reference int sum(vector<int>&);
– Notice that likely the computer passes the address to
sum() but you should just think of dat as an alias for x int main()
{
int result;
vector<int> x = {1,2,3,4};
result = sum(x);
}
Type Expression
C++ Reference Var Address-of (yields a pointer)
& (int &val, vector<int> &vec) &val => int *, &vec = vector<int>*
19
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
DYNAMIC ALLOCATION
20
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Dynamic Memory & the Heap
22
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
C Dynamic Memory Allocation
void* malloc(int num_bytes) function in stdlib.h
– Allocates the number of bytes requested and returns a pointer to the block
of memory
– Use sizeof(type) macro rather than hardcoding 4 since the size of an int
may change in the future or on another system
free(void * ptr) function
– Given the pointer to the (starting location of the) block of memory, free returns it to
the system for re-use by subsequent malloc calls
#include <iostream>
#include <cstdlib>
using namespace std;
int main(int argc, char *argv[])
{
int num;
cout << “How many students?” << endl;
cin >> num;
int *scores = (int*) malloc( num*sizeof(int) );
// can now access scores[0] .. scores[num-1];
free(scores);
return 0;
}
23
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
C++ new & delete operators
new allocates memory from heap
– followed with the type of the variable you want or an array type
declaration
• double *dptr = new double;
• int *myarray = new int[100];
– can obviously use a variable to indicate array size
– returns a pointer of the appropriate type
• if you ask for a new int, you get an int * in return
• if you ask for an new array (new in't[10]), you get an int * in return]
delete returns memory to heap
– followed by the pointer to the data you want to de-allocate
• delete dptr;
– use delete [] for pointers to arrays
• delete [] myarray;
24
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Dynamic Memory Allocation
25
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Fill in the Blanks
________ data = new int;
26
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Fill in the Blanks
________ data = new int;
– int*
________ data = new char;
– char*
________ data = new char[100];
– char*
________ data = new char*[20];
– char**
________ data = new vector<string>;
– vector<string>*
________ data = new Student;
– Student*
27
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Dynamic Allocation
// Computes rectangle area,
Dynamic Allocation // prints it, & returns it
– Lives on the heap int area(int, int);
void print(int);
• Doesn't have a name, only pointer/address to it
int main()
– Lives until you 'delete' it {
• Doesn't die at end of function int wid = 8, len = 5, a;
(though pointer to it may) area(wid,len);
}
Let's draw these as boxes in the heap area
int* area(int w, int l)
{
Stack Area of RAM Heap Area of RAM int* ans = new int;
*ans = w * l;
return ans;
0xbe0 0x93c ans }
area 0xbe4 8 w
0x93c 40
0xbe8 5 l
0xbec Return
004000ca0 link
0xbf0 8 wid
main 0xbf4 5 len
0xbf8 -73249515 a
0xbfc Return
00400120 link
28
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Dynamic Allocation
// Computes rectangle area,
Dynamic Allocation // prints it, & returns it
– Lives on the heap int area(int, int);
void print(int);
• Doesn't have a name, only pointer/address to it
int main()
– Lives until you 'delete' it {
• Doesn't die at end of function int wid = 8, len = 5, a;
(though pointer to it may) area(wid,len);
}
Let's draw these as boxes in the heap area
int* area(int w, int l)
{
Stack Area of RAM Heap Area of RAM int* ans = new int;
*ans = w * l;
return ans;
}
0x93c 40
MEMORY LEAK
No one saved a
0xbf0 8 wid pointer to this data
main 0xbf4 5 len
0xbf8 -73249515 a
0xbfc Return
00400120 link
29
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Dynamic Allocation
// Computes rectangle area,
Dynamic Allocation // prints it, & returns it
– Lives on the heap int area(int, int);
void print(int);
• Doesn't have a name, only pointer/address to it
int main()
– Lives until you 'delete' it {
• Doesn't die at end of function int wid = 8, len = 5, a;
(though pointer to it may) area(wid,len);
}
Let's draw these as boxes in the heap area
int* area(int w, int l)
{
Stack Area of RAM Heap Area of RAM int* ans = new int;
ans = &w;
return ans;
0xbe0 0x93c ans }
area 0xbe4 8 w
0x93c 40
0xbe8 5 l
0xbec Return
004000ca0 link MEMORY LEAK
0xbf0 8 wid
main 0xbf4 5 len
0xbf8 -73249515 a
0xbfc Return
00400120 link
30
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Dynamic Allocation
// Computes rectangle area,
Be sure you keep a pointer around // prints it, & returns it
somewhere otherwise you'll have a memory int area(int, int);
void print(int);
leak
int main()
{
int wid = 8, len = 5, a;
area(wid,len);
}
34
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Object Assignment
Assigning one struct or class object to another
will cause an element by element copy of the
source data destination struct or class
#include<iostream>
using namespace std;
0x00 ‘B’
enum {CS, CECS };
0x01 ‘i’
struct student { name
… …
char name[80]; s1
int id; 0x4F 00
int major; 0x50 5 id
}; 0x54 1 major
int main(int argc, char *argv[]) ‘B’
…
{ ‘i’
student s1; name
…
strncpy(s1.name,”Bill”,80); … s2
s1.id = 5; s1.major = CS; 00
…
5 id
student s2 = s1;
1 major
return 0;
} Memory
35
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Memory Allocation Tips
Take care when returning a pointer or reference that the
object being referenced will persist beyond the end of a
function
Take care when assigning a returned referenced object to
another variable…you are making a copy
Try the examples yourself
– $ wget http://ee.usc.edu/~redekopp/cs104/memref.cpp
36
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved
Understanding Memory Allocation
There are no syntax errors. Which of these can correctly build an
Item and then have main() safely access its data
class Item class Item class Item
{ public: { public: { public:
Item(int x, string y); Item(int x, string y); Item(int x, string y);
}; };
};
Item buildItem() Item& buildItem()
Item* buildItem()
{ Item x(4, “hi”); { Item x(4, “hi”);
{ Item* x = new Item(4,“hi”);
return x; return x;
return x;
} }
}
int main() int main()
int main()
{ Item i = buildItem(); { Item& i = buildItem();
{ Item *i = buildItem();
// access i’s data. // access i’s data
// access i’s data
}
}
ex1 ex2 } ex3
Item
on
Build Build Build Heap
0xbe4 4 x 0xbe4 4 x
Item Item Item
0xbe8 "hi" 0xbe8 "hi" 0xbe8 0x93c x
0xbec Return Return 0xbec Return
004000ca0 link
0xbec 004000ca0 link
004000ca0 link
39
© Copyright 2013 Brent Nash & Mark Redekopp, All Rights Reserved